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

From: Tassilo Horn <[email-masked]>
Date: Wed, 12 Feb 2025 11:53:29 +0100

Richard Stallman <[email-masked]> writes:

Hi Richard,

> [[[ To any NSA and FBI agents reading my email: please consider    ]]]
> [[[ whether defending the US Constitution against all enemies,     ]]]
> [[[ foreign or domestic, requires you to follow Snowden's example. ]]]
>
>       > (defmacro my-foo (exp)
>       >   (with-uninterned-symbols
>       >    `(let ((x$ 6))
>       >       (+ x$ ,exp))))
>
> with-uninterned-symbols does not seem to exist in my checkout.
> Is it new?  Proposed?

Yes, I've proposed it but as it stands, it's already declined. That's
totally acceptable for me given the details of eager macro expansion
Stefan M. explained to me.

> I can guess from the example what it does.  It is terribly un-Lispy.
> Let's use this syntax instead:
>
>    (with-uninterned-symbols (x)
>      `(let ((,x 6))
>         (+ ,x ,exp)))
>
> It adds just one list of variables to the overall syntactic complexity
> of the construct when used, and it adds nothing to the syntax of Lipp.
>
> We could use the name `with-gensyms', a shorter name.

That's already available, named cl-with-gensyms and defined in
cl-macs.el.  But truth to be told, that exhibits the very same problem
that my proposed macro also has, i.e., that

  (equal (macroexpand '(cl-with-gensyms (x)
                         `(+ ,x ,x)))
         (macroexpand '(cl-with-gensyms (x)
                         `(+ ,x ,x))))
  ;;=> t

meaning that every expansion uses the very same uninterned symbol x, not
one unique symbol x per expansion.  As Stefan explained, that can lead
to problems in certain (honestly quite uncommon) corner-cases.

Bye,
Tassilo