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

From: Stefan Monnier <[email-masked]>
Date: Sun, 09 Feb 2025 18:34:55 -0500

> Why?

I'd ask the author of the code.

> I would expect that it's one set of uninterned symbols per expansion.

Try:

    (defmacro my-foo (exp)
      (with-uninterned-symbols
       `(let ((x$ 6))
          (+ x$ ,exp))))

and then check (equal (macroexpand '(my-foo r)) (macroexpand '(my-foo r)))
[ Admittedly, this all depends on when `with-uninterned-symbols` is
  macro-expanded, but in most cases it will be macro-expanded once and
  for all when the macro is defined.  ]

> Doesn't that contradict your statement?

Apparently not.  🙂

> Oh, and obviously you made me curious about those weird corner cases.
> Please elaborate! ;-)

I wish I could.  I'm starting to wonder if I dreamed it.
The best I could come up with is:

    (defmacro my-countref-let (var form &rest body)
      (with-uninterned-symbols
       `(let ((x$ ,form)
              (count$ 0))
          (cl-symbol-macrolet ((,var (progn (cl-incf count$) x$)))
            (unwind-protect
                (progn ,@body)
              (message "%S ref'd %d times" ',var count$))))))

where (my-countref-let v1 67 (my-countref-let v2 89 (+ v1 v2))) will say
that `v2` was referenced twice and `v1` zero times (at least if that
macro is byte-compiled).

        Stefan