GNU bug report logs -
#76132
Clojure-style auto-gensyms for macros
Previous Next
Reported by: Tassilo Horn <tsdh <at> gnu.org>
Date: Fri, 7 Feb 2025 21:13:02 UTC
Severity: wishlist
Tags: patch
Done: Tassilo Horn <tsdh <at> gnu.org>
Bug is archived. No further changes may be made.
Full log
Message #53 received at 76132 <at> debbugs.gnu.org (full text, mbox):
>> [ 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. ]
> Well, my naive assumption about macro expansion is that it's done lazily
> from inside-out.
Interesting: that's impossible.
Think about a case like:
(dolist (push pushes) (message "%S" `(pop ,push)))
how can the macro expander decide whether or not `(push pushes)` and
`(pop ,push)` are calls to macros `push` and `pop` without first
macro-expanding `dolist` and backquote?
Similarly, we can't compile the above code without first expanding all
the macros.
> And furthermore, why does
>
> (defmacro th/my-foo (exp)
> (let ((x (make-symbol "x")))
> `(let ((,x 6))
> (+ ,x ,exp))))
>
> not exhibit the exactly same problem?
Because the above code says explicitly that `make-symbol` is called
every time a call to `th/my-foo` is expanded. Whereas in your version,
the code says that `make-symbol` is called every time a call to
`with-uninterned-symbols` is expanded, but that can happen either when
we define `my-foo` or when "use" my-foo (depending on whether the
macroexpansion is done lazily or eagerly, and it can't be done lazily
if we compile the macro).
> Is there a way to fix my macro?
I don't think so, in general. E.g. if you want to generate fresh new
uninterned symbols every time the code is executed, then you can't
compile something like
(with-uninterned-symbols
(let ((x$ 6))
(+ x$ exp)))
since the name of the variable is not known until runtime (and will be
different each time).
I think to fix it, you have to fuse your macro with backquote, so users
would write
(defmacro my-other-foo (exp)
(uninterned-backquote
(let ((x$ 6))
(+ x$ ,exp))))
but of course you could still support the syntax
(defmacro my-foo (exp)
(with-uninterned-symbols
`(let ((x$ 6))
(+ x$ ,exp))))
and simply have `with-uninterned-symbols` check that its argument is of
the form `(...) and treat it as a use of `uninterned-backquote`.
Stefan
This bug report was last modified 147 days ago.
Previous Next
GNU bug tracking system
Copyright (C) 1999 Darren O. Benham,
1997,2003 nCipher Corporation Ltd,
1994-97 Ian Jackson.