On Sun, Nov 02, 2025 at 09:20:50AM -0500, Peter McGoron via Chicken-users wrote:
> I have a macro that generates another macro. It uses the letrec trick to
> generate temporaries to use as binders in the left-hand-side of the
> generated syntax-rules.
> 
> The following code, when pasted into csi (and chibi, as a test) does the
> correct thing:
> 
> (define-syntax define-alist-macro
>   (syntax-rules ()
>     ((_ name (ids ...))
>      (define-alist-macro "generate" name (ids ...) ()))
>     ((_ "generate" name (id ids ...) (acc ...))
>      (define-alist-macro "generate" name (ids ...) ((cons id tmp) acc ...)))
>     ((_ "generate" name () ((cons id tmp) ...))
>      (define-syntax name
>        (syntax-rules ...* ()
>          ((_ tmp ...) (list (cons (quote id) tmp) ...)))))))
> (define-alist-macro test (a b c d))
> (display (test 4 3 2 1))
> 
> This displays "((d . 4) (c . 3) (b . 2) (a . 1))".

Hello Peter,

I think you might be relying on undefined behaviour here.
The spec says:

> If a literal identifier is inserted as a
> free identifier then it refers to the binding of that identifier
> within whose scope the instance of syntax-rules appears.

This leaves it open to interpretation whether free identifiers in
recursive invocation of the same macro ought to be the same identifier
or different ones.  Different Schemes seem to differ in their
interpretation of this.

For example, MIT Scheme gives an error while expanding the final rule:
;Duplicate vars in pattern: (#[syntactic-closure 20 _] #[syntactic-closure 21 
tmp] #[syntactic-closure 22 tmp] #[syntactic-closure 23 tmp] 
#[syntactic-closure 24 tmp])

Gambit does the same:
> (define-alist-macro test (a b c d))
*** ERROR -- duplicate pattern variable

Bigloo also gives an error:
*** ERROR:define-alist-macro:
No matching clause -- (hygiene.r5rs.mark1001define-alist-macro 
hygiene.r5rs.mark1001tmp hygiene.r5rs.mark1001hygiene.r5rs.mark1001tmp 
hygiene.r5rs.mark1001hygiene.r5rs.mark1001hygiene.r5rs.mark1001tmp 
hygiene.r5rs.mark1001hygiene.r5rs.mark1001hygiene.r5rs.mark1001hygiene.r5rs.mark1001tmp)

However, Scheme48, Guile, Gauche, SISC and Racket seem to agree with
Chibi and csi.

And of course, it's a bit unfortunate that csi and csc disagree on
what to do here.  I think that has to do with the fact that macros get
compiled to a "flat" form.  This is basically bug #1832:
https://bugs.call-cc.org/ticket/1832
I've added your code to this ticket because it's a simpler case
triggering the same underlying issue.

Unfortunately we don't have a proper solution for this yet.

Cheers,
Peter

Reply via email to