[Top][All Lists]

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Feature request: Expose `ellipsis?' from

From: Mark H Weaver
Subject: Re: Feature request: Expose `ellipsis?' from
Date: Fri, 23 Nov 2018 15:25:18 -0500
User-agent: Gnus/5.13 (Gnus v5.13) Emacs/26.1 (gnu/linux)

Hi Marc,

Marc Nieper-Wißkirchen <address@hidden> writes:

> Am Mi., 21. Nov. 2018 um 04:38 Uhr schrieb Mark H Weaver <address@hidden>:
>  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.


reply via email to

[Prev in Thread] Current Thread [Next in Thread]