emacs-lisp-style-guide icon indicating copy to clipboard operation
emacs-lisp-style-guide copied to clipboard

Use uninterned symbols in expanded let-forms of macros

Open TobiasZawada opened this issue 5 years ago • 3 comments

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

TobiasZawada avatar Jun 19 '19 09:06 TobiasZawada

Agreed, I've seen this in quite some projects around where things worked just by accident of naming being "compatible".

Fuco1 avatar Jun 19 '19 10:06 Fuco1

Wed Jun 19 17:03:21 BST 2019

Question - wouldn't this be a use case for gensym?

rprimus avatar Jun 19 '19 16:06 rprimus

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.

Fuco1 avatar Jun 19 '19 16:06 Fuco1