emacs-lisp-style-guide
emacs-lisp-style-guide copied to clipboard
Use uninterned symbols in expanded let-forms of macros
Use uninterned symbols in expanded let-forms of macros if the values of these symbols are for macro-internal use only.
;; bad:
(defmacro i-interned (&rest body)
(declare (debug (body)))
`(let ((i 1))
(progn
(message "Macro internal value of i: %s" i)
,@body)))
;; good:
(defmacro i-uninterned (&rest body)
(declare (debug (body)))
(let ((i (make-symbol "i")))
`(let ((,i 1))
(progn
(message "Macro internal value of i: %s" ,i)
,@body))))
(let ((i 0))
(i-interned
(message "Value of i: %s" i)))
(let ((i 0))
(i-uninterned
(message "Value of i: %s" i)))
Output in the *Messages* buffer:
Macro internal value of i: 1
Value of i: 1
Macro internal value of i: 1
Value of i: 0
Agreed, I've seen this in quite some projects around where things worked just by accident of naming being "compatible".
Wed Jun 19 17:03:21 BST 2019
Question - wouldn't this be a use case for gensym
?
You can use gensym
or make-symbol
, the end result is the same except make-symbol
has nicer naming when you macroexpand. gensym
is actually a wrapper around make-symbol
. But yea, doesn't matter much.