From mboxrd@z Thu Jan 1 00:00:00 1970 Path: news.gmane.io!.POSTED.blaine.gmane.org!not-for-mail From: Philip McGrath 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: 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?= 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: 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 ) 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 ) 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 ) 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 ) 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: X-ME-Received: X-ME-Proxy-Cause: gggruggvucftvghtrhhoucdtuddrgedvhedrudekledgtdejucetufdoteggodetrfdotf fvucfrrhhofhhilhgvmecuhfgrshhtofgrihhlpdfqfgfvpdfurfetoffkrfgpnffqhgen uceurghilhhouhhtmecufedttdenucesvcftvggtihhpihgvnhhtshculddquddttddmne goufhushhpvggtthffohhmrghinhculdegledmnecujfgurhephffvvefufffkjghfgggt sehgtderredttdejnecuhfhrohhmpefrhhhilhhiphcuofgtifhrrghthhcuoehphhhilh hiphesphhhihhlihhpmhgtghhrrghthhdrtghomheqnecuggftrfgrthhtvghrnhepkefh hfejkeeihfdvgfekleefkeffveehgfevfffgleegtefhteekffelkeethfehnecuffhomh grihhnpehuthgrhhdrvgguuhdpghhithhhuhgsrdhiohenucevlhhushhtvghrufhiiigv pedtnecurfgrrhgrmhepmhgrihhlfhhrohhmpehphhhilhhiphesphhhihhlihhpmhgtgh hrrghthhdrtghomh X-ME-Proxy: 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: 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" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-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: --nextPart3575643.LM0AJKV5NW Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="UTF-8"; protected-headers="v1" From: Philip McGrath 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 : > > Message: 1 > > Date: Sun, 26 Feb 2023 02:45:12 -0500 > > From: "Philip McGrath" > > To: "Maxime Devos" , Ludovic Court=C3=A8s > >=20 > > , "Matt Wette" , > > guile-devel@gnu.org > >=20 > > Cc: "Christine Lemmer-Webber" > > 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--