GNU bug report logs - #76132
Clojure-style auto-gensyms for macros

Previous Next

Package: emacs;

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 #32 received at 76132 <at> debbugs.gnu.org (full text, mbox):

From: Tassilo Horn <tsdh <at> gnu.org>
To: Stefan Monnier <monnier <at> iro.umontreal.ca>
Cc: 76132 <at> debbugs.gnu.org
Subject: Re: bug#76132: Clojure-style auto-gensyms for macros
Date: Sat, 08 Feb 2025 17:12:00 +0100
Stefan Monnier <monnier <at> iro.umontreal.ca> writes:

>> 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).

Why? I would expect that it's one set of uninterned symbols per
expansion.  I first tried implementing it with an alist instead of a
hash-table and didn't think about the fact that my alist function arg is
just a pointer to the head of the list so that when popping back from a
recursive call where I pushed onto the list (that is, to its head), the
new entry got lost.  With that failing approach, every foo$ occurrence
was substituted with a separate (make-symbol "foo"), so although the
exansion looked correct, every #:foo in there was distinct from all
other #:foo-s.  Doesn't that contradict your statement?

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

Bye,
Tassilo




This bug report was last modified 165 days ago.

Previous Next


GNU bug tracking system
Copyright (C) 1999 Darren O. Benham, 1997,2003 nCipher Corporation Ltd, 1994-97 Ian Jackson.