From mboxrd@z Thu Jan 1 00:00:00 1970 Path: news.gmane.org!.POSTED!not-for-mail From: =?UTF-8?Q?Marc_Nieper=2DWi=C3=9Fkirchen?= Newsgroups: gmane.lisp.guile.devel Subject: Re: Feature request: Expose `ellipsis?' from psyntax.ss Date: Fri, 23 Nov 2018 22:06:05 +0100 Message-ID: References: <875zwzmq4n.fsf@netris.org> <87pnv6iss7.fsf@netris.org> <87k1leip2i.fsf@netris.org> <124085ab-2a76-4892-e790-d58b07bcb3fc@nieper-wisskirchen.de> <87lg5tj3gn.fsf@netris.org> <874lcgzj9p.fsf@netris.org> <871s7fuml7.fsf@netris.org> <87d0qwqlbb.fsf@netris.org> NNTP-Posting-Host: blaine.gmane.org Mime-Version: 1.0 Content-Type: multipart/alternative; boundary="000000000000b609e6057b5b5ae0" X-Trace: blaine.gmane.org 1543008128 20879 195.159.176.226 (23 Nov 2018 21:22:08 GMT) X-Complaints-To: usenet@blaine.gmane.org NNTP-Posting-Date: Fri, 23 Nov 2018 21:22:08 +0000 (UTC) Cc: guile-devel@gnu.org To: mhw@netris.org Original-X-From: guile-devel-bounces+guile-devel=m.gmane.org@gnu.org Fri Nov 23 22:22:04 2018 Return-path: Envelope-to: guile-devel@m.gmane.org Original-Received: from lists.gnu.org ([208.118.235.17]) by blaine.gmane.org with esmtp (Exim 4.84_2) (envelope-from ) id 1gQItn-0005KB-Kw for guile-devel@m.gmane.org; Fri, 23 Nov 2018 22:22:03 +0100 Original-Received: from localhost ([::1]:54315 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gQIvu-0004Ni-9N for guile-devel@m.gmane.org; Fri, 23 Nov 2018 16:24:14 -0500 Original-Received: from eggs.gnu.org ([2001:4830:134:3::10]:48435) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gQItq-00028b-Pt for guile-devel@gnu.org; Fri, 23 Nov 2018 16:22:11 -0500 Original-Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1gQIea-0006sR-5E for guile-devel@gnu.org; Fri, 23 Nov 2018 16:06:23 -0500 Original-Received: from mail-pg1-f174.google.com ([209.85.215.174]:42608) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1gQIeZ-0006qp-Ry for guile-devel@gnu.org; Fri, 23 Nov 2018 16:06:20 -0500 Original-Received: by mail-pg1-f174.google.com with SMTP id d72so3478671pga.9 for ; Fri, 23 Nov 2018 13:06:18 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:mime-version:references:in-reply-to:from:date :message-id:subject:to:cc; bh=NcaIFDMt1RU8BwKMGJsc+iEC92PQx3SP5c5nMCxfNK8=; b=plLXeAiFhdiy8Q1P/WOokCT73+cMuTeN5UqhIQXlviCLIkwBV+W5iN7ob4l4GdWhw3 SuyIr/BzR/RWHB9hvyendVlxpMJzLqG+Oxk8Brozy02LW+0PcHvb0FOfhCA8SLBP4Df8 TtTwgi2PXZlWnBcib2uQj6LSeMWMFx6td3Nb0v+mvqtz5jW77pL9iGaGVJDHz+t/bXG4 xF0zZgUcwz5uOoSi3YN9nmGKCqEyXseMgu42venbPI7e/cewQmCziWzkmPsu/czxQZOM sHd2bw3zE4KNtY86KUXQhEsTJx0rv7xbpAeZCx67L1wJ834zWyGUslo+aiBCg6m1OOzb QuEQ== X-Gm-Message-State: AA+aEWblOQw2cn8upUTWGE6vx9yjeYFa+gsft/NDHYTkMEuwVHYCR0MC eZt3QY+Bu67wW24HihZcaFs6JZ1vXVtYrZerry8= X-Google-Smtp-Source: AFSGD/U35qf6TxD3GtwSkvPZHiBvSOaQPCV5XiUXxT/FP+GOpt3CEh5umRhwR2zNa3gE+6fDlcsWOgTADaY3Oq7pxJk= X-Received: by 2002:a63:88c7:: with SMTP id l190mr15214651pgd.110.1543007177671; Fri, 23 Nov 2018 13:06:17 -0800 (PST) In-Reply-To: <87d0qwqlbb.fsf@netris.org> X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] [fuzzy] X-Received-From: 209.85.215.174 X-BeenThere: guile-devel@gnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: "Developers list for Guile, the GNU extensibility library" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: guile-devel-bounces+guile-devel=m.gmane.org@gnu.org Original-Sender: "guile-devel" Xref: news.gmane.org gmane.lisp.guile.devel:19762 Archived-At: --000000000000b609e6057b5b5ae0 Content-Type: text/plain; charset="UTF-8" Content-Transfer-Encoding: quoted-printable Hi Mark, Am Fr., 23. Nov. 2018 um 08:56 Uhr schrieb Mark H Weaver : > Hi Marc, > > Marc Nieper-Wi=C3=9Fkirchen writes: > > > Am Mi., 21. Nov. 2018 um 04:38 Uhr schrieb Mark H Weaver >: > > > > > Ellipsis identifiers are a bit more tricky, because unlike other > > > bindings, the user-visible ellipsis identifiers are not actually > > > substituted. We can't do that because ellipsis identifiers can be > used > > > for other purposes, e.g. bound to ordinary variables or macros, and > > > these two ways of binding ellipsis identifiers should not shadow ea= ch > > > other. > > Sorry, this was a weak argument. I've since remembered the _actual_ > reason that it needs to be done this way: > > In general, for any sensible binding form, bindings with different names > should not shadow each other. For example, a binding for 'E' should not > shadow a binding for 'F'. > > If you try to model (with-ellipsis E BODY) as binding 'E', then it is > not a sensible binding form in this sense. Unlike any sensible binding > form, (with-ellipsis E BODY) should not only shadow outer bindings of > 'E', but *any* outer ellipsis binding, whether '...' or 'F' or something > else. In other words, in this model, there can be only one binding of > this kind in a given lexical context. > Alternatively, it would be enough for all use cases that come to my mind if `(with-ellipsis E BODY)' besides binding `E' would shadow `...' and nothing else. E.g. under this alternative semantics, in the BODY of `(with-ellipsis E (with-ellipsis F BODY))' both `E' and `F' would function as ellipses, while `...' would not. In other case, `with-ellipsis' would work like the following macro transformer: (lambda (stx) (syntax-case stx () ((k e body) (with-syntax ((::: (datum->syntax k '...))) #'(let-syntax ((::: ) (e )) body))))) This way, `with-ellipsis' would behave more like an ordinary (albeit unhygienic) binding construct. Therefore, I think this is a bad model for 'with-ellipsis'. > > 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. > > Does that make sense? > So CURRENT-ELLIPSIS would be the name of an identifier whose name is disjoint to all names a user could use for their identifiers? Or would you model CURRENT-ELLIPSIS as a parameter object, which would entail a different semantics? > Note that in this later model, it's not natural for (with-ellipsis E > BODY) to shadow a binding for 'E' or vice versa, because 'E' is not > actually the thing being bound by 'with-ellipsis'. > > In theory, we could introduce additional mechanisms to force > (with-ellipsis E BODY) to shadow bindings for 'E' and vice versa. This > would entail changing *every* binding form to check if the identifier > being bound matches the current binding of CURRENT-ELLIPSIS, and if so, > somehow invalidating the ellipsis binding. It's not obvious what should > be done in this case. > > We could do something like this, but in my view, it would be an ad-hoc > addition to the semantics in order to support the inadequate mental > model where (with-ellipsis E BODY) is thought of as binding 'E'. > > What do you think? > I agree with you that trying to shadow bindings for `E' in a model in which `with-ellipsis' does not actually bind `E' but some other identifier is the opposite of being beautiful. So I don't think one should try to do this in this model. We have, however, the semantics of R[67]RS, where `...' has an actual binding as auxiliary syntax. This allows to have more than one identifier acting as the ellipsis at the same time (just import `...' from `(scheme base)' or `(rnrs base)' under two different names). Whatever model for `with-ellipsis' is chosen, it should work well with `R[67]RS'. It just comes to my mind that this rules out my model from above (the syntax transformer that rebinds `...'). :-) So, here may be a better model: Each lexical scope has a flag ORIGINAL-ELLIPSIS?. In the top-level scope, the flag is set. As long as the flag is set, `syntax-case' and `syntax' check for the ellipsis by using `free-identifier=3D?' and comparing with the binding for `...' as exported = by `(rnrs base)'. Now, `(with-syntax e BODY)' clears this flag in BODY and binds `e' to a special ellipsis value. Alternatively, in the model where `with-ellipsis' should not bind anything, `ORIGINAL-ELLIPSIS?' becomes your `CURRENT-ELLIPSIS'. As long as it is unset, `syntax-case' and `syntax' check for the ellipsis by using `free-identifier=3D?' as above. When `CURRENT-ELLIPSIS' is bound to `e', th= e checking is done with `(bound-identifier=3D? e ---)'. -- Marc --000000000000b609e6057b5b5ae0 Content-Type: text/html; charset="UTF-8" Content-Transfer-Encoding: quoted-printable
Hi Mark,

Am Fr., 23. Nov. 2018 um 08:56=C2=A0Uhr schrieb Mark H Weaver <mhw@netris.org>:
Hi Marc,

Marc Nieper-Wi=C3=9Fkirchen <marc@nieper-wisskirchen.de> writes:

> Am Mi., 21. Nov. 2018 um 04:38 Uhr schrieb Mark H Weaver <mhw@netris.org>:
>
>=C2=A0 >=C2=A0 Ellipsis identifiers are a bit more tricky, because u= nlike other
>=C2=A0 >=C2=A0 bindings, the user-visible ellipsis identifiers are n= ot actually
>=C2=A0 >=C2=A0 substituted.=C2=A0 We can't do that because ellip= sis identifiers can be used
>=C2=A0 >=C2=A0 for other purposes, e.g. bound to ordinary variables = or macros, and
>=C2=A0 >=C2=A0 these two ways of binding ellipsis identifiers should= not shadow each
>=C2=A0 >=C2=A0 other.

Sorry, this was a weak argument.=C2=A0 I've since remembered the _actua= l_
reason that it needs to be done this way:

In general, for any sensible binding form, bindings with different names should not shadow each other.=C2=A0 For example, a binding for 'E' = should not
shadow a binding for 'F'.

If you try to model (with-ellipsis E BODY) as binding 'E', then it = is
not a sensible binding form in this sense.=C2=A0 Unlike any sensible bindin= g
form, (with-ellipsis E BODY) should not only shadow outer bindings of
'E', but *any* outer ellipsis binding, whether '...' or = 9;F' or something
else.=C2=A0 In other words, in this model, there can be only one binding of=
this kind in a given lexical context.

A= lternatively, it would be enough for all use cases that come to my mind if = `(with-ellipsis E BODY)' besides binding `E' would shadow `...'= and nothing else. E.g. under this alternative semantics, in the BODY of `(= with-ellipsis E (with-ellipsis F BODY))' both `E' and `F' would= function as ellipses, while `...' would not. In other case, `with-elli= psis' would work like the following macro transformer:

(lambda (stx)
=C2=A0 (syntax-case stx ()
=C2=A0 =C2=A0 ((k e body)<= /div>
=C2=A0 =C2=A0 =C2=A0(with-syn= tax ((::: (datum->syntax k '...)))
=C2=A0 =C2=A0 =C2=A0 =C2=A0#'(let-syntax ((::: <= undefined>) (e <ellipsis>))
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0body)))))

This way, `with-ellipsis' would behave more like= an ordinary (albeit unhygienic) binding construct.=C2=A0

Therefore, I think this is a bad model fo= r 'with-ellipsis'.

I think it makes more sense to model (with-ellipsis E BODY) as
introducing a new lexical binding with a fixed name.=C2=A0 CURRENT-ELLIPSIS=
would be a good name if we wanted to make it part of the public API.=C2=A0 = In
this model, 'E' becomes the _value_ of the binding, instead of the<= br> binding's name.

Does that make sense?

So CURRENT-ELLIPS= IS would be the name of an identifier whose name is disjoint to all names a= user could use for their identifiers? Or would you model CURRENT-ELLIPSIS = as a parameter object, which would entail a different semantics?
= =C2=A0
Note that in this later model, i= t's not natural for (with-ellipsis E
BODY) to shadow a binding for 'E' or vice versa, because 'E'= ; is not
actually the thing being bound by 'with-ellipsis'.

In theory, we could introduce additional mechanisms to force
(with-ellipsis E BODY) to shadow bindings for 'E' and vice versa.= =C2=A0 This
would entail changing *every* binding form to check if the identifier
being bound matches the current binding of CURRENT-ELLIPSIS, and if so,
somehow invalidating the ellipsis binding.=C2=A0 It's not obvious what = should
be done in this case.

We could do something like this, but in my view, it would be an ad-hoc
addition to the semantics in order to support the inadequate mental
model where (with-ellipsis E BODY) is thought of as binding 'E'.
What do you think?

I agree with you tha= t trying to shadow bindings for `E' in a model in which `with-ellipsis&= #39; does not actually bind `E' but some other identifier is the opposi= te of being beautiful. So I don't think one should try to do this in th= is model.

We have, however, the semantics of R[67]= RS, where `...' has an actual binding as auxiliary syntax. This allows = to have more than one identifier acting as the ellipsis at the same time (j= ust import `...' from `(scheme base)' or `(rnrs base)' under tw= o different names). Whatever model for `with-ellipsis' is chosen, it sh= ould work well with `R[67]RS'.

It just comes t= o my mind that this rules out my model from above (the syntax transformer t= hat rebinds `...'). :-)

So, here may be a bett= er model: Each lexical scope has a flag ORIGINAL-ELLIPSIS?. In the top-leve= l scope, the flag is set. As long as the flag is set, `syntax-case' and= `syntax' check for the ellipsis by using `free-identifier=3D?' and= comparing with the binding for `...' as exported by `(rnrs base)'.= Now, `(with-syntax e BODY)' clears this flag in BODY and binds `e'= to a special ellipsis value.

Alternatively, in th= e model where `with-ellipsis' should not bind anything, `ORIGINAL-ELLIP= SIS?' becomes your `CURRENT-ELLIPSIS'. As long as it is unset, `syn= tax-case' and `syntax' check for the ellipsis by using `free-identi= fier=3D?' as above. When `CURRENT-ELLIPSIS' is bound to `e', th= e checking is done with `(bound-identifier=3D? e ---)'.

<= /div>
-- Marc
--000000000000b609e6057b5b5ae0--