From mboxrd@z Thu Jan  1 00:00:00 1970
Path: news.gmane.io!.POSTED.blaine.gmane.org!not-for-mail
From: Philip McGrath <philip@philipmcgrath.com>
Newsgroups: gmane.lisp.guile.devel
Subject: Re: [PATCH] add language/wisp to Guile?
Date: Sun, 26 Feb 2023 18:22:39 -0500
Message-ID: <3517394.V25eIC5XRa@bastet>
References: <mailman.886.1677397547.13386.guile-devel@gnu.org>
 <CAEYrNrSa+U4ZCwa5G_vkR1WJH17H_-QBcnPnOrM7FafjP7gJPQ@mail.gmail.com>
Mime-Version: 1.0
Content-Type: multipart/signed; boundary="nextPart3575643.LM0AJKV5NW";
 micalg="pgp-sha512"; protocol="application/pgp-signature"
Injection-Info: ciao.gmane.io; posting-host="blaine.gmane.org:116.202.254.214";
	logging-data="30885"; mail-complaints-to="usenet@ciao.gmane.io"
Cc: Marc =?ISO-8859-1?Q?Nieper=2DWi=DFkirchen?= <marc@nieper-wisskirchen.de>
To: guile-devel@gnu.org
Original-X-From: guile-devel-bounces+guile-devel=m.gmane-mx.org@gnu.org Mon Feb 27 00:23:27 2023
Return-path: <guile-devel-bounces+guile-devel=m.gmane-mx.org@gnu.org>
Envelope-to: guile-devel@m.gmane-mx.org
Original-Received: from lists.gnu.org ([209.51.188.17])
	by ciao.gmane.io with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256)
	(Exim 4.92)
	(envelope-from <guile-devel-bounces+guile-devel=m.gmane-mx.org@gnu.org>)
	id 1pWQMY-0007nf-AL
	for guile-devel@m.gmane-mx.org; Mon, 27 Feb 2023 00:23:27 +0100
Original-Received: from localhost ([::1] helo=lists1p.gnu.org)
	by lists.gnu.org with esmtp (Exim 4.90_1)
	(envelope-from <guile-devel-bounces@gnu.org>)
	id 1pWQM0-000804-D1; Sun, 26 Feb 2023 18:22:52 -0500
Original-Received: from eggs.gnu.org ([2001:470:142:3::10])
 by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256)
 (Exim 4.90_1) (envelope-from <philip@philipmcgrath.com>)
 id 1pWQLy-0007zv-Ug
 for guile-devel@gnu.org; Sun, 26 Feb 2023 18:22:50 -0500
Original-Received: from wout3-smtp.messagingengine.com ([64.147.123.19])
 by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256)
 (Exim 4.90_1) (envelope-from <philip@philipmcgrath.com>)
 id 1pWQLw-0006XS-Dk
 for guile-devel@gnu.org; Sun, 26 Feb 2023 18:22:50 -0500
Original-Received: from compute4.internal (compute4.nyi.internal [10.202.2.44])
 by mailout.west.internal (Postfix) with ESMTP id 772D532000EB;
 Sun, 26 Feb 2023 18:22:46 -0500 (EST)
Original-Received: from mailfrontend2 ([10.202.2.163])
 by compute4.internal (MEProxy); Sun, 26 Feb 2023 18:22:46 -0500
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=
 philipmcgrath.com; h=cc:cc:content-type:date:date:from:from
 :in-reply-to:in-reply-to:message-id:mime-version:references
 :reply-to:sender:subject:subject:to:to; s=fm1; t=1677453766; x=
 1677540166; bh=ZiEAONehrm7VGJQ86O2WU3A/yJAdxXyjeVZ/z+en7Hg=; b=K
 jQQ+wjzdjq5UjCoA3YRiSjdUnlrK1Uw4h5s0+3EPjYjhSeqEXkdWmVIjijAtyR2D
 y3KmLQdkNvs37MucoYFoBAcNYm0/9bb09A1kvznzi2zXoPetTSqgCMYzKAQkw8dr
 wGbOOvydsOlH10qOGMhsOSlKg1Kayafb0HlngJnr6Pb/1KzqOHLs1MT1yKYhxOW+
 4XK1RMicDsjdVhZIJND15Ig5e+RRCs51F8jkvLjYMb6oPlSyW0OMB2F9aFRJX5xi
 UUEfMLkqEXi2rjAefGdtc5pvWwPyDLuABGYYZj/yMHea3j3NlOCD5l1dN8XDUK2K
 3jiFCX3L9C3sU3dzSVJ1w==
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=
 messagingengine.com; h=cc:cc:content-type:date:date:feedback-id
 :feedback-id:from:from:in-reply-to:in-reply-to:message-id
 :mime-version:references:reply-to:sender:subject:subject:to:to
 :x-me-proxy:x-me-proxy:x-me-sender:x-me-sender:x-sasl-enc; s=
 fm1; t=1677453766; x=1677540166; bh=ZiEAONehrm7VGJQ86O2WU3A/yJAd
 xXyjeVZ/z+en7Hg=; b=QdSmPSCC/BJ3f3krXF9vIQS7jD9qeaLhRMOI01lHB48z
 Q6XbBQS/7dIRNpguY6ZAKTUyvL5fvybWpPh6ODadqYx9wTadiDBtcCdOKoVvLkP0
 ZtJBDFHu65FyYdytdZLAbzNdQP5QulgkSVd04r3SZf40nR72orhZbcU1Cz1S+ZKJ
 gA/hvsic8/38I93FT4dFfJTk4KojZYahRhLl2Hs0x8I3THQvzk9aOR5KBB4Mx3yH
 hHtSLFFdtbuhvRHMRIAA5WcyehhInwKT/ih4FZTNRGQtyTT+Lb3LgcPtuq5vH4Ku
 SluAMrJlVtGtuT+FqL/7pT24g3g5FSG3d0P7s5Xowg==
X-ME-Sender: <xms:xen7Y-CJih7IHWWuEgHN04jlBWcxqVw2B8wm7Wxw2GrTYIu44o6ESA>
 <xme:xen7Y4gQUhtBbRTqm_aJzgTpr_7zTZC5ui9H1qdoIcRKznN8Ep-5D3tzehHEOM3cJ
 OZRHX8IDRi92Em8FEY>
X-ME-Received: <xmr:xen7YxmSi4EcrhCHOgwkO-_Z1DKTlxzaBA9UNLnODVSiQ7EFWpMLiNuAOVvi7FMcfYii3shy2nnr_HdukxHXWc02Q4hTVIPz8xWrKzMe>
X-ME-Proxy-Cause: gggruggvucftvghtrhhoucdtuddrgedvhedrudekledgtdejucetufdoteggodetrfdotf
 fvucfrrhhofhhilhgvmecuhfgrshhtofgrihhlpdfqfgfvpdfurfetoffkrfgpnffqhgen
 uceurghilhhouhhtmecufedttdenucesvcftvggtihhpihgvnhhtshculddquddttddmne
 goufhushhpvggtthffohhmrghinhculdegledmnecujfgurhephffvvefufffkjghfgggt
 sehgtderredttdejnecuhfhrohhmpefrhhhilhhiphcuofgtifhrrghthhcuoehphhhilh
 hiphesphhhihhlihhpmhgtghhrrghthhdrtghomheqnecuggftrfgrthhtvghrnhepkefh
 hfejkeeihfdvgfekleefkeffveehgfevfffgleegtefhteekffelkeethfehnecuffhomh
 grihhnpehuthgrhhdrvgguuhdpghhithhhuhgsrdhiohenucevlhhushhtvghrufhiiigv
 pedtnecurfgrrhgrmhepmhgrihhlfhhrohhmpehphhhilhhiphesphhhihhlihhpmhgtgh
 hrrghthhdrtghomh
X-ME-Proxy: <xmx:xen7Y8wWny8VfVxsqnpNs-uyL0wKpHmCnpluPbBn0E_r-hWSeahaLA>
 <xmx:xen7YzTBi133A8n25NsoxiGmrZFAYaUyhArENyMvRlxI4kbpRlj-xw>
 <xmx:xen7Y3aX7Bgv7H93LbI14tVxZfcy2K6Ks0otNr_m_DYWkgMEaQp__g>
 <xmx:xun7YxO25XcoF1ukaGRdPM0lLkjFLfy6aH8t99NZaMMuyPh15FrWHg>
Feedback-ID: i2b1146f3:Fastmail
Original-Received: by mail.messagingengine.com (Postfix) with ESMTPA; Sun,
 26 Feb 2023 18:22:45 -0500 (EST)
In-Reply-To: <CAEYrNrSa+U4ZCwa5G_vkR1WJH17H_-QBcnPnOrM7FafjP7gJPQ@mail.gmail.com>
Received-SPF: pass client-ip=64.147.123.19;
 envelope-from=philip@philipmcgrath.com; helo=wout3-smtp.messagingengine.com
X-Spam_score_int: -11
X-Spam_score: -1.2
X-Spam_bar: -
X-Spam_report: (-1.2 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1,
 DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1,
 RCVD_IN_DNSWL_LOW=-0.7, SPF_HELO_PASS=-0.001, SPF_PASS=-0.001,
 URI_DOTEDU=1.644 autolearn=no autolearn_force=no
X-Spam_action: no action
X-BeenThere: guile-devel@gnu.org
X-Mailman-Version: 2.1.29
Precedence: list
List-Id: "Developers list for Guile,
 the GNU extensibility library" <guile-devel.gnu.org>
List-Unsubscribe: <https://lists.gnu.org/mailman/options/guile-devel>,
 <mailto:guile-devel-request@gnu.org?subject=unsubscribe>
List-Archive: <https://lists.gnu.org/archive/html/guile-devel>
List-Post: <mailto:guile-devel@gnu.org>
List-Help: <mailto:guile-devel-request@gnu.org?subject=help>
List-Subscribe: <https://lists.gnu.org/mailman/listinfo/guile-devel>,
 <mailto:guile-devel-request@gnu.org?subject=subscribe>
Errors-To: guile-devel-bounces+guile-devel=m.gmane-mx.org@gnu.org
Original-Sender: guile-devel-bounces+guile-devel=m.gmane-mx.org@gnu.org
Xref: news.gmane.io gmane.lisp.guile.devel:21752
Archived-At: <http://permalink.gmane.org/gmane.lisp.guile.devel/21752>

--nextPart3575643.LM0AJKV5NW
Content-Transfer-Encoding: quoted-printable
Content-Type: text/plain; charset="UTF-8"; protected-headers="v1"
From: Philip McGrath <philip@philipmcgrath.com>
To: guile-devel@gnu.org
Subject: Re: [PATCH] add language/wisp to Guile?
Date: Sun, 26 Feb 2023 18:22:39 -0500
Message-ID: <3517394.V25eIC5XRa@bastet>
MIME-Version: 1.0

Hi,

On Sunday, February 26, 2023 6:02:04 AM EST Marc Nieper-Wi=C3=9Fkirchen wro=
te:
> Am So., 26. Feb. 2023 um 08:46 Uhr schrieb <guile-devel-request@gnu.org>:
> > Message: 1
> > Date: Sun, 26 Feb 2023 02:45:12 -0500
> > From: "Philip McGrath" <philip@philipmcgrath.com>
> > To: "Maxime Devos" <maximedevos@telenet.be>, Ludovic Court=C3=A8s
> >=20
> >         <ludo@gnu.org>, "Matt Wette" <matt.wette@gmail.com>,
> >         guile-devel@gnu.org
> >=20
> > Cc: "Christine Lemmer-Webber" <cwebber@dustycloud.org>
> > Subject: Re: [PATCH] add language/wisp to Guile?
> > Message-ID: <981b0e74-96c0-4430-b693-7fc8026e3ead@app.fastmail.com>
> > Content-Type: text/plain;charset=3Dutf-8
>=20
> [...]
>=20
> I would like to make two remarks, which I think are essential to get
> the semantics right.
>=20
> The R6RS comments of the form "#!r6rs" are defined to modify the
> lexical syntax of the reader; possibly, they don't change the language
> semantics (after reading).  In particular, "#!r6rs" also applies to
> data files but does not affect the interpretation of the data after it
> is read. It cannot because the reader otherwise ignores and does not
> report comments.
>=20
> Thus a comment of the form "#!r6rs" may be suitable for Wisp, but it
> is not a substitute for Racket's "#lang" (or a similar mechanism).
> Guile shouldn't confuse these two different levels of meaning.
>=20

I agree that it's important to distinguish between lexical syntax (`read`) =
and=20
the semantics of what is read.

However, Racket's `#lang` in fact operates entirely at the level of `read`.=
=20
(Racketeers contribute to confusion on this point by using `#lang` as a=20
shorthand for Racket's entire language-creation infrastructure, when in fac=
t=20
`#lang` specifically has a fairly small, though important, role.) When `rea=
d`=20
encounters `#lang something`, it looks up a reader extension procedure in t=
he=20
module indicated by `something` and uses that procedure to continue parsing=
=20
the input stream into data. Importantly, while syntax objects may be used t=
o=20
attach source location information, there is no "lexical context" or bindin=
g=20
information at this stage, as one familiar with syntax objects from macro=20
writing might expect: those semantics come after `read` has finished parsin=
g=20
the input stream from bytes to values.

Nonetheless, because the reader extension procedure has complete control ov=
er=20
what data is read, a `#lang` language's reader can produce data with the=20
semantics the language's author intends.

Before I go on to give some examples, I would note that of course R6RS give=
s=20
implementations great freedom in how they use `#!implementation-specific` t=
o=20
extend the lexical syntax, and some ways that some implementations use it=20
would be awkward at best to express by treating `#!` as an alternate spelli=
ng=20
for `#lang `: Chez Scheme's `#!base-rtd` and `#!bwp` come to mind in that=20
category.=20

Now some examples, where `with-module-reading-parameterization` configures=
=20
`read` to the right state for reading a module. (When reading generic data,=
=20
reader extension procedures are turned off by default.)

```
philip@bastet:~$ racket=20
Welcome to Racket v8.8 [cs].
=2D> (require syntax/modread)
=2D> (define (read-module str)             =20
     (with-module-reading-parameterization
       (lambda ()                        =20
         (read (open-input-string str)))))
=2D> (read-module "#lang racket (eqv? 1.5 (/ 3 2))")
'(module anonymous-module racket (#%module-begin (eqv? 1.5 (/ 3 2))))
=2D> (read-module "#lang exact-decimal racket (eqv? 1.5 (/ 3 2))")
'(module anonymous-module racket (#%module-begin (eqv? 3/2 (/ 3 2))))
```

Here the `exact-decimal` meta-language parameterizes the call to the base=20
language's reader, changing lexical syntax like "1.5" to be read as an exac=
t=20
number instead of an inexact number. Chez Scheme's `#!fold-case` and `#!no-
fold-case` directives are somewhat similar in spirit.

Most Racket `#lang` languages are more like this example:

```
=2D> (read-module "#lang racket (lambda (x) (+ 1 x))")
'(module anonymous-module racket (#%module-begin (lambda (x) (+ 1 x))))
=2D> (read-module "#lang typed/racket (lambda (x) (+ 1 x))")
'(module anonymous-module typed/racket (#%module-begin (lambda (x) (+ 1 x))=
))
```

Here, the lexical syntax is the same: the only difference is whether the=20
resulting `module` form has `racket` or `typed/racket` as its "initial impo=
rt"=20
or "language". However, the semantics are starkly different: the `#lang rac=
ket`=20
example is a perfectly good program, but attempting to macro-expand the `#l=
ang=20
typed/racket` program fails with the following error:

```
Type Checker: type mismatch
  expected: Number
  given: Any in: x
```

Much of the power of Racket's language infrastructure comes from the each=20
`module` form specifying its "language"/"initial import", which dates from=
=20
"Composable and Compilable Macros: You Want it When?" (ICFP 2002) [1], long=
=20
before the addition of `#lang`. You can write a `module` form explicitly,=20
without using a `#lang`-based reader extension.

Doing this sort of thing is less elegant and convenient with R6RS `library`=
=20
forms, but it's certainly possible to produce an R6RS library form where=20
`lambda` and `+` have semantics different than the versions exported from t=
he=20
`(rnrs)` library.

=46or a variation on the theme, consider:

```
=2D> (read-module "#lang web-server
    (require racket/serialize)
    (serialize (=CE=BB (x) x))")
'(module anonymous-module web-server/lang
   (#%module-begin (require racket/serialize) (serialize (=CE=BB (x) x))))
```

=46irst, note that the resulting datum refers to `web-server/lang`, not `we=
b-
server`: in this particular case, the mismatch is a historical accident tha=
t=20
confused me once (so I remember it), but it does illustrate how `#lang`=20
maintains the distinction between the reader and the expander.

The example also illustrates semantic change. The `#%module-begin` form fro=
m=20
the web server language performs a whole-module transformation on its subfo=
rms=20
to make continuations serializable, thus producing "Automatically RESTful W=
eb=20
Applications" [2]. Likewise, it's `lambda` form, unlike the version from=20
`racket/base`, creates serializable closures.

=46inally, here's a more dramatic example:

```
=2D> (define (read-module* str)
     (with-module-reading-parameterization
       (lambda ()
         ;; avoid a bug
         (syntax->datum (read-syntax #f (open-input-string str))))))
=2D> (read-module* "#lang datalog
   parent(creusa, ascanius). =20
   parent(anchises, aeneas).
   parent(aeneas, ascanius).
   parent(hecuba, creusa). =20
   parent(priam, creusa).=20
   ancestor(A, B) :- parent(A, B).
   ancestor(A, B) :- parent(A, C), ancestor(C, B).
   ancestor(A, ascanius)?")
'(module anonymous-module datalog/sexp/lang
   (#%module-begin
    (! (parent creusa ascanius))
    (! (parent anchises aeneas))
    (! (parent aeneas ascanius))
    (! (parent hecuba creusa))
    (! (parent priam creusa))
    (! (:- (ancestor A B) (parent A B)))
    (! (:- (ancestor A B) (parent A C) (ancestor C B)))
    (? (ancestor A ascanius))))
```

Even when `#lang` is working at the fullest extent of its powers, its job i=
s=20
merely to `read` the input byte stream and produce an S-expression.

> The second comment concerns the shebang line in R6RS scripts (as
> described in the non-normative appendices).  The shebang line is not a
> comment in the R6RS lexical syntax; it does not even reach the reader
> - at least, conceptionally.  The Scheme reader only sees the lines
> following the shebang line.
>=20
> For example, a conforming R6RS implementation must raise an exception
> when trying to read (using get-datum, for example) a file that begins
> with a shebang line.
>=20
> Thus, the shebang line doesn't need to be considered when discussing
> comment formats in lexical syntax.
>=20

This is a very persuasive account of the R6RS appendices. I just find the=20
approach somewhat unsatisfying. An R6RS implementation with script support=
=20
must have a procedure `not-quite-read` that handles a potential shebang lin=
e=20
before calling `read`. I wish this `not-quite-read` procedure were made=20
available from some Scheme library (and perhaps somewhat more explicitly=20
specified), and I'd probably find it most beautiful for this `not-quite-rea=
d` to=20
be unified with `read`. But that's not really relevant per se.

>=20
> Best,
>=20
> Marc

Thank you for these thought-provoking remarks!

Philip

[1]: https://www-old.cs.utah.edu/plt/publications/macromod.pdf
[2]: https://jeapostrophe.github.io/home/static/icfp065-mccarthy.pdf
--nextPart3575643.LM0AJKV5NW
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQIzBAABCgAdFiEE9GWrrNY3rqwUFVXPygNjjfo/HHoFAmP76b8ACgkQygNjjfo/
HHoh6g//W1tQMopqHurJL8RM0zhGNgXtht4JKdkzfe1o6/wBt+TXSQRCfkaK4hsk
uUMmVnFJOLO9nuQRmwBhrJi6Qw+sK2PdLUVishfpMlHxQ5Ck6puRRSoohKppY/aw
BaKa+XH6ZLwHIDQ3for2QtyTT/If+q/rG/qRD4aCnn4bFC2Jpa0Xf47+PJm7slsO
7WzCgfQSZzMRqDgxqf/7clmzDs+ZS+j7MgCpM5WExBHTKVIzEIzx0xkkPq8a7zG5
uqECDwQSwuSpQPh0gqEZUkVX2INsv3wJPmoLx2aQJnQzAa5UyyZjSwfa5O6Wh6+w
TKen8Fa21AlKPOw1SD+tGBzpIkOVsloScrsc+GYZY2Vr6r69+uC7G2DWKd2l8xYJ
LQ+HoExRNUdIKF3hJR/1S49zzHpqrz15gOZ2bPSgVWNZakV2GT/nO7eQMBCAgnwH
ZE7kHIL2aI6H0oQRvoq2vPXfvn5zfE++KXeOME1hhYRY0UYMk4moERFXV5U/qQ4F
UeDqSRmcwQVgHNvWd0vxfqxSUbyK1hr13/Z+gadr0+fg7xvfv+OAJJH84N+lP+pU
pL2nf7RY7YuOM8dpnC19g7K+n6BwSTvNc/+ux42QJlwh/dRfnV7e7xp53WNUeJiQ
Uy8YEhmCcQLA88TzqrTwNzRsxqvfHhPLn+QyPdvSUQsUwuDv2Qo=
=wUnX
-----END PGP SIGNATURE-----

--nextPart3575643.LM0AJKV5NW--