帮我看看这个宏是哪有问题

每个make-symbol生成的symbol都是独一无二(uninterned symbol)的,如果不这么做,就没法根本上保证用了gensym之后宏可以卫生,这和intern生成的symbol不同,intern生成的symbol会放入变量obarray保存起来。有

(eq (make-symbol "sym") (make-symbol "sym"))
;; => nil

(eq (intern "sym") (intern "sym"))
;; => t

正确的玩法是用let保存一个uninterned symbol到变量里,然后用这个变量。

(defmacro with-mode-on (mode &rest body)
  (declare (indent defun)
           (doc-string 3))
  (let ((sym (make-symbol (concat (symbol-name mode) "-p"))))
    `(let ((,sym ,mode))
       (unless ,sym (,mode 1))
       ,@body
       (unless ,sym (,mode -1)))))
2 个赞