Hi Marc, Marc Nieper-Wißkirchen <m...@nieper-wisskirchen.de> writes:
> Am Mi., 21. Nov. 2018 um 04:38 Uhr schrieb Mark H Weaver <m...@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 '...'. 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. What do you think? Also, for the sake of completeness I should explain a remaining detail of Guile's semantics for 'with-ellipsis' bindings. In my previous response, I wrote: > I think it makes more sense to model (with-ellipsis E BODY) as > introducing a new lexical binding with a fixed name. CURRENT-ELLIPSIS > would be a good name if we wanted to make it part of the public API. In > this model, 'E' becomes the _value_ of the binding, instead of the > binding's name. In existing versions of Guile, the special fixed name is equivalent to: (datum->syntax E '#{ $sc-ellipsis }#) Where E is the identifier being bound or checked. In particular, the _marks_ from E are copied to the special fixed name, both when binding a new ellipsis identifier and when checking for ellipsis identifier. In other words, for each set of marks there's a distinct ellipsis binding. WARNING: Note that the name #{ $sc-ellipsis }# is not part of Guile's API, and is subject to change. We reserve the right to change its name, or to make it completely inaccessible in future versions of Guile. For example, we might move the ellipsis bindings out of the substitution and into a separate field in the wrap which maps marks to ellipsis identifiers, with no name involved at all. I welcome input on these questions. Mark