Subject: bug#76132: Clojure-style auto-gensyms for macros

From: Stefan Monnier <[email-masked]>
Date: Sat, 08 Feb 2025 10:29:07 -0500

> Clojure has a very convenient feature to make that easy.  While you can
> write such macros traditionally like
>
> (defmacro foo [x y]
>   (let [xv (gensym "x")
>         yv (gensym "y")]
>     `(let [,xv ,x
>            ,yv ,y]
>        (do-stuff (* ,xv ,xv) (* ,yv ,yv)))))
>
> you can also write much more concise and convenient
>
> (defmacro foo [x y]
>   `(let [xv# ,x
>          yv# ,y]
>      (do-stuff (* xv# xv#) (* yv# yv#))))

IIUC the two versions above aren't quite equivalent.
The Clojure version seems to behave similarly to the macro you propose,
which behaves more like:

    (let [xv (gensym "x")
          yv (gensym "y")]
      (defmacro foo [x y]
        `(let [,xv ,x
               ,yv ,y]
           (do-stuff (* ,xv ,xv) (* ,yv ,yv)))))

in the sense that the same uninterned symbols will be used for every
expansion.  This is usually fine, but can still result in name capture
in some weird corner cases (tho I must admit I can't even remember what
those corner cases are).

> I'm very hesitant to extend the Emacs Lisp language with such
> features, when this can be had for a price of a simple function call.
> We have enough magic names and punctuation characters already, and
> they get in the way of code readability.

To the extent that it's all implemented within a normal macro
(i.e. doesn't touch things like the reader or the `macroexp.el` code),
I'm not too bothered.  It could even live in a separate package if we
don't want it in core.

        Stefan