Am Fr., 23. Nov. 2018 um 21:26 Uhr schrieb Mark H Weaver <
mhw@netris.org>:
Hi Marc,
Marc Nieper-Wißkirchen <marc@nieper-wisskirchen.de> writes:
> Am Mi., 21. Nov. 2018 um 04:38 Uhr schrieb Mark H Weaver <mhw@netris.org>:
>
> I'm not aware of any language in the R[567]RS that makes it clear
> whether '...' should be recognized as an ellipsis if it is bound to a
> variable. The Scheme implementations I tried do not seem to agree.
>
> For example, consider this example:
>
> (let ((... 'hello))
> (let-syntax ((foo (syntax-rules ()
> ((foo x ...)
> '((x) ...)))))
> (foo 1 2)))
>
> If '...' is recognized as an ellipsis within the 'let', then the result
> will be '((1) (2)). Otherwise, the result will be '((1) 2).
>
> I just tested with Chez Scheme 9.5 as well. It returns the same result as Chibi, namely '((1) 2).
>
> I found that Racket 7.0, Chicken 4.13.0, and Scheme48 1.9.2 return
> '((1) (2)). Chibi-Scheme returns '((1) 2). I see the same results
> with this variant:
>
> (let-syntax ((... (syntax-rules ())))
> (let-syntax ((foo (syntax-rules ()
> ((foo x ...)
> '((x) ...)))))
> (foo 1 2)))
>
> Again, Chez returns '((1) 2).
>
> If we instead bind '...' as a top-level variable:
>
> (define-syntax ... (syntax-rules ()))
> (let-syntax ((foo (syntax-rules ()
> ((foo x ...)
> '((x) ...)))))
> (foo 1 2))
>
> Then all four of these Schemes agree that the answer is '((1) (2)),
> including Chibi-Scheme.
>
> Chez Scheme still returns '((1) 2) and thus does not recognize `...'
> as the ellipsis.
I stand by the analysis in my previous response in this thread, but
nonetheless I've since realized that given the current implementation of
'ellipsis?' in psyntax.scm, Guile *should* be returning '((1) 2) in
these examples above, and I'm not sure why that's not happening.
The reason is that when no ellipsis binding is present, Guile currently
uses 'free-identifier=?' to compare identifiers with #'(... ...) in
psyntax.scm, where '...' has no binding. In the examples above, the
ellipsis identifiers are within a lexical environment where '...' is
bound, so 'free-identifier=?' should be returning #false in these cases.
Having said this, given the analysis in my previous response, I'm now
wondering whether it's a mistake to use 'free-identifier=?' to check for
the default ellipsis '...'.
Using `free-identifier=?' to check for the default ellipsis is definitely correct. `bound-identifier=?' would not give the correct results in R[67]RS because the ellipsis can be imported under several names. Or use a macro that produces aliases of the ellipsis:
(import (scheme base))
(define-syntax foo
(syntax-rules ()
((foo e) TEMPLATE)))
(foo ...)
In TEMPLATE, both `...' and `e' have to be the ellipsis. They are `free-identifier=?' but not `bound-identifier=?'.
Within the lexical scope of
'with-ellipsis', Guile uses 'bound-identifier=?' to check for the
user-defined ellipsis, but perhaps we should be using it uniformly to
check for ellipsis in all cases.
Using `free-identifier=?' would only make sense in a model, in which `(with-ellipsis E BODY)' actually binds `E', wouldn't it? In any case, inside the scope of `with-ellipsis', the behavior of `syntax-case', `syntax' differs substantially with respect to the ellipsis from the behavior outside of `with-ellipsis'. Thus it coud very well be that we need `bound-identifier=?' in scopes inside `with-ellipsis' and `free-identifier=?' in scopes outside.