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: Mon, 27 Feb 2023 23:27:39 -0500 Message-ID: <2267642.HovnAMPojK@bastet> References: <3517394.V25eIC5XRa@bastet> Mime-Version: 1.0 Content-Type: multipart/signed; boundary="nextPart3234803.0WQXIW03uk"; micalg="pgp-sha512"; protocol="application/pgp-signature" Injection-Info: ciao.gmane.io; posting-host="blaine.gmane.org:116.202.254.214"; logging-data="24639"; mail-complaints-to="usenet@ciao.gmane.io" Cc: guile-devel@gnu.org To: Marc =?ISO-8859-1?Q?Nieper=2DWi=DFkirchen?= Original-X-From: guile-devel-bounces+guile-devel=m.gmane-mx.org@gnu.org Tue Feb 28 05:28:20 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 1pWrb8-00069O-DG for guile-devel@m.gmane-mx.org; Tue, 28 Feb 2023 05:28:19 +0100 Original-Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1pWrak-00055g-Ql; Mon, 27 Feb 2023 23:27:54 -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 1pWrai-00055U-IJ for guile-devel@gnu.org; Mon, 27 Feb 2023 23:27:52 -0500 Original-Received: from out1-smtp.messagingengine.com ([66.111.4.25]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1pWrag-0005B6-6Y for guile-devel@gnu.org; Mon, 27 Feb 2023 23:27:52 -0500 Original-Received: from compute6.internal (compute6.nyi.internal [10.202.2.47]) by mailout.nyi.internal (Postfix) with ESMTP id CD1375C0113; Mon, 27 Feb 2023 23:27:45 -0500 (EST) Original-Received: from mailfrontend1 ([10.202.2.162]) by compute6.internal (MEProxy); Mon, 27 Feb 2023 23:27:45 -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=1677558465; x= 1677644865; bh=yN/pdLMd3vXNGEzKIA/Ejmnro1sVXub4YDhcRGl0w7k=; b=p 94TQWeUUUIucKI0mkpNgMghw4Tn6K/HpbtXeqiuE7vKXuW1JCh90NgJWz4UYY3xT X8kG1SfqI/Abu40wB9tQUeCiCt0xGk+IFCh1I6onP0q9LKhzs7yJw2bVyseK9W1x W0YxLAJp1Ds2TnlcsZSNAgdUjb4oLElEn/NOG88kfSxlIfgIka5wrTy/i39/ijNi yqFHOzyqW7pP3K7a/3eMqxFgf95NbmHEVzmZIscEu9uEOXVbLXtnIf3mLUjmpe4F PMzswN+7AF/RwwjvbMgR3+MyUy7fWGl+/DwvL8w+jDIb3s7JSSjYQNaOmf7igake f7F4YHcT3eXc8D3oEeAIw== 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=1677558465; x=1677644865; bh=yN/pdLMd3vXNGEzKIA/Ejmnro1sV Xub4YDhcRGl0w7k=; b=HG0p2cT666ripTqkspmzmi05csBITFDvPC7CqKaBBYGk SS3eZ0OYnK6UcFpayDXVZcEuuxtq4QJ/RLnLsyIQ1U3GqidRhoZG1AqFqG7SGXZ+ 2rwgXYYdR76AfnU4BhKwccjjnrIYVEDmir/hubId/drttNi6aRF3cW3/om1ez7qr WpRO6P9nKl7WojBurHk7zbO+/4rWae3/xKLApYubJIU2XXDOxDi3h6EW2xiEoQQm q64xr2IU6+YI0mAMFRYnDEtd2VxuSirJPUMHY6komUYaFXFoRYwuVq2Krh9xVcov 8CnTAZxZG4+H9H1VPDAAuEOU1nSJZca4UAXBtugGqg== X-ME-Sender: X-ME-Received: X-ME-Proxy-Cause: gggruggvucftvghtrhhoucdtuddrgedvhedrudeluddgjedtucetufdoteggodetrfdotf fvucfrrhhofhhilhgvmecuhfgrshhtofgrihhlpdfqfgfvpdfurfetoffkrfgpnffqhgen uceurghilhhouhhtmecufedttdenucesvcftvggtihhpihgvnhhtshculddquddttddmne cujfgurhephffvvefufffkjghfgggtsehgtderredttdejnecuhfhrohhmpefrhhhilhhi phcuofgtifhrrghthhcuoehphhhilhhiphesphhhihhlihhpmhgtghhrrghthhdrtghomh eqnecuggftrfgrthhtvghrnhephedvveffvefgveeftdeliefgjeevieekteevveevhedt leetfefhvdfhheejkefhnecuffhomhgrihhnpehriehrshdrohhrghdprhgrtghkvghtqd hlrghnghdrohhrghenucevlhhushhtvghrufhiiigvpedtnecurfgrrhgrmhepmhgrihhl fhhrohhmpehphhhilhhiphesphhhihhlihhpmhgtghhrrghthhdrtghomh X-ME-Proxy: Feedback-ID: i2b1146f3:Fastmail Original-Received: by mail.messagingengine.com (Postfix) with ESMTPA; Mon, 27 Feb 2023 23:27:45 -0500 (EST) In-Reply-To: Received-SPF: pass client-ip=66.111.4.25; envelope-from=philip@philipmcgrath.com; helo=out1-smtp.messagingengine.com X-Spam_score_int: -27 X-Spam_score: -2.8 X-Spam_bar: -- X-Spam_report: (-2.8 / 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, RCVD_IN_MSPIKE_H3=0.001, RCVD_IN_MSPIKE_WL=0.001, SPF_HELO_PASS=-0.001, SPF_PASS=-0.001 autolearn=ham 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:21756 Archived-At: --nextPart3234803.0WQXIW03uk Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="UTF-8"; protected-headers="v1" From: Philip McGrath Cc: guile-devel@gnu.org Subject: Re: [PATCH] add language/wisp to Guile? Date: Mon, 27 Feb 2023 23:27:39 -0500 Message-ID: <2267642.HovnAMPojK@bastet> MIME-Version: 1.0 Hi, On Monday, February 27, 2023 2:26:47 AM EST Marc Nieper-Wi=C3=9Fkirchen wro= te: > Am Mo., 27. Feb. 2023 um 00:22 Uhr schrieb Philip McGrath >=20 > : > > Hi, > >=20 > > On Sunday, February 26, 2023 6:02:04 AM EST Marc Nieper-Wi=C3=9Fkirchen= wrote: > > > 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 (`rea= d`) > > and the semantics of what is read. > >=20 > > However, Racket's `#lang` in fact operates entirely at the level of > > `read`. > > (Racketeers contribute to confusion on this point by using `#lang` as a > > shorthand for Racket's entire language-creation infrastructure, when in > > fact `#lang` specifically has a fairly small, though important, role.) > > When `read` encounters `#lang something`, it looks up a reader extension > > procedure in the module indicated by `something` and uses that procedure > > to continue parsing the input stream into data. Importantly, while synt= ax > > objects may be used to attach source location information, there is no > > "lexical context" or binding information at this stage, as one familiar > > with syntax objects from macro writing might expect: those semantics co= me > > after `read` has finished parsing the input stream from bytes to values. >=20 > [...] >=20 > Thank you for the reminder on Racket's #lang mechanism; it is a long > time ago since I wrote some #lang extensions myself when experimenting > with Racket. >=20 > Nevertheless, I am not sure whether it is relevant to the point I > tried to make. The "#!r6rs" does not indicate a particular language > (so tools scanning for "#!r6rs" cannot assume that the file is indeed > an R6RS program/library).=20 I think I had missed that some of your remarks are specifically about the "#!r6rs" directive, not directives of the form "#!" more genera= lly.=20 I agree that implementations have more responsibilities with respect to "#!r6rs", that the presence of "#!r6rs" in a file is not enough to conclude= =20 that the file is an R6RS program/library, and that a straightforward=20 implementation of "#!r6rs" as reading like "#lang r6rs" in the manner of my= =20 previous examples would not conform to R6RS. Also, on the broader question, my first preference would be for Guile to=20 implement `#lang language/wisp`, not least to avoid the confusing subtletie= s=20 here and the potential for humans to confuse `#!language/wisp` with a sheba= ng=20 line. I raise the possibility of `#!language/wisp` only as an alternative i= f=20 people are more comfortable using a mechanism that R6RS specifically design= ed=20 for implementation-defined extensions. Nonetheless, I'll try to explain why I think "#!r6rs" can be handled, and i= s=20 handled by Racket, consistently with both "#lang r6rs" and the behavior=20 specified in the report. >=20 > Of course, R6RS gives implementations the freedom to modify the reader > in whatever way after, say, "#!foo-baz" was read. Thus, "#!foo-baz" > could be defined to work like Racket's "#lang foo-baz," reading the > rest of the source as "(module ...)". But as long as we stay within > the confines of R6RS, this will only raise an undefined exception > because, in general, "module" is not globally bound. >=20 Before getting to the general point, specifically about "module" not being= =20 bound: in Racket, a root-level `module` form is handled quite similarly to = the=20 `library` form in R6RS, which says in 7.1 [1]: >>>> The names `library`, `export`, `import`, [...] appearing in the librar= y=20 syntax are part of the syntax and are not reserved, i.e., the same names ca= n=20 be used for other purposes within the library or even exported from or=20 imported into a library with different meanings, without affecting their us= e in=20 the `library` form.=20 None of the libraries defined in R6RS export a binding for `library`: inste= ad,=20 the implementation must recognize it somehow, whether by handling it as a=20 built-in or binding it in some environment not standardized by R6RS. (The `racket/base` library/language does in fact export a binding for `modu= le`=20 which can be used to create submodules with the same syntax as a root-level= =20 `module`, but that isn't relevant to the handling of a `root-level` module= =20 form itself.) > I don't want to contradict you; I just mean that a plain "#!r6rs" > without a top-level language where "module" is bound is not equivalent > to "#lang" and that trying to switch to, say, Elisp mode with > "#!elisp" would leave the boundaries of the Scheme reports (and when > this is done, this specific discussion is moot). >=20 > [...] >=20 > (It must be compatible with calling the procedures "read" and "eval" > directly, so "#!r6rs" must not wrap everything in some module form, > say.) Now I'll try to sketch Racket's handling of "#!r6rs" from an R6RS perspecti= ve.=20 =46or the sake of a concrete example, lets consider this program: ``` #!r6rs (library (demo) (export x) (import (rnrs base)) (define x (+ 1 #!r6rs 2))) ``` Using R6RS's `read`/`get-datum` and `write` on such input produces the datu= m=20 (with linebreaks for legibility): ``` (library (demo) (export x) (import (rnrs base)) (define x (+ 1 2))) ``` Racket is an implementation of the sort contemplated by Appendix A [2]: >>>> [T]he default mode offered by a Scheme implementation may be non- conformant, and such a Scheme implementation may require special settings o= r=20 declarations to enter the report-conformant mode. When Racket begins reading a module's source code, the reader is in a non- conformant mode. The first "#!r6rs" lexeme is the required "declaration[] t= o=20 enter the report-conformant mode". From that point on, the import is read w= ith=20 a reader as specified in R6RS, with no extensions. Thus, the second "#!r6rs= "=20 lexeme, as the report specifies, is treated as a comment. (Since the reader= is=20 already in strict R6RS mode, it has no side-effect.) Racket's reader (as noted, in `with-module-reading-parameterization` mode)= =20 produces the following datum: ``` (module anonymous-module r6rs (#%module-begin (library (demo) (export x) (import (rnrs base)) (define x (+ 1 2))))) ``` Racket's reader has adjusted the "declaration[] to enter the report-conform= ant=20 mode" to an explicitly-parenthesized form, but the portion of the input rea= d=20 in report-conformant mode produced the same datum as above. The important point here is that the `read` and `eval` procedures from=20 `racket/base` are not the same as the `read` and `eval` from `(rnrs io=20 simple)` and `(rnrs eval)`, respectively. The R6RS version of `read` does n= ot=20 introduce a `module` form, and the R6RS version of `eval` happily evaluates= =20 the forms that the R6RS `read` produces. It's a bit of a tangent here, but for the broader discussion about `#lang` = or=20 similar it might be interesting to note that, in addition to this=20 "declaration[] to enter the report-conformant mode" that can be written in- band in a report-conformant source file, Racket also has out-of-band ways t= o=20 enter R6RS "report-conformant mode". In particular, Racket distributes an=20 executable `plt-r6rs` that can run and compile R6RS programs that do not=20 necessarily start with `#!r6rs`. [3] Invoking it instead with the form `plt-r6rs --install =E2=80=B9libraries-file=E2=80=BA` will read `=E2=80=B9l= ibraries-file=E2=80=BA`, which need=20 not begin with `#!r6rs`, with the R6RS-conformant reader. The =E2=80=B9libr= aries-file=E2=80=BA=20 should contain R6RS library forms, each of which will be installed to its o= wn=20 file, located where Racket would expect to load the R6RS library with its=20 declared name. In the process of installing the libraries, `plt-r6rs` adds = a=20 `#!r6rs` directive at the beginning of each file. [4] > In an implementation that supports, say, > R6RS and R7RS, "#!r6rs" can only switch the lexical syntax but cannot > introduce forms that make the implementation change the semantics from > R7RS to R6RS, e.g., in the case of unquoted vector literals. I'm not very familiar with R7RS, and, quickly skimming R7RS Small, I didn't= =20 see a notion of directives other than `#!fold-case` and `#!no-fold-case`.=20 (That's a bit ironic, given that the R6RS editors seem to have contemplated `#!r7rs` *before* they considered `#!r6rs`.) I think a similar technique co= uld=20 work in this case, though. From an R6RS perspective, at least, an=20 implementation could implement a directive such that the `read` from `(rnrs= )`=20 would parse: >>>> #!r7rs #(1 2 3) as: >>>> (quote #(1 2 3)) The other direction is a bit trickier, but the R7RS specification for `read= `=20 from `(scheme base)` does say that "implementations may support extended=20 syntax to represent record types or other types that do not have datum=20 representations." It seems an implementation could define a type "non-self- evaluating-vector" and have `read` from `(scheme base)` produce a value of= =20 that type when given: >>>> #!r6rs #(1 2 3) Presumably `eval` from `(scheme eval)` would raise an error if asked to=20 evaluate such a datum, as it does if asked to evaluate an unquoted (), but= =20 `quote` from `(scheme base)` would arrange to replace such a datum with a=20 vector. (I'm not at all sure that an implementation *should* do such a thing: I'm o= nly=20 trying to explain why I don't think the Scheme reports prohibit it.) =2DPhilip [1]: http://www.r6rs.org/final/html/r6rs/r6rs-Z-H-10.html#node_sec_7.1 [2]: http://www.r6rs.org/final/html/r6rs-app/r6rs-app-Z-H-3.html#node_chap_A [3]: https://docs.racket-lang.org/r6rs/Running_Top-Level_Programs.html [4]: https://docs.racket-lang.org/r6rs/Installing_Libraries.html --nextPart3234803.0WQXIW03uk 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/HHoFAmP9grsACgkQygNjjfo/ HHo1aQ/+NY5TebAS/WA6cx5eChKFHo41thYT5xAy5SBYg3vNI1XELpJgJsEcThKk bpwKe/br6q6YLzAjP+tPw56BMoHOTwQzJwYc/r6/3/TAnv35SvcX+zM5BSAuIYCK lbNncu/BJOMHUzXdkH0w6dJxn/rqbnsGmGAiSo22uhPuaqRl//Vk2y2zdpi9IlbS 7c6Iv7eH7tzu9jrJqvyD5GRsz1iaNMyudimpo8eqXj1W7/Y6bMcSIJmdA/v3te8F rnCxQ/re/EU8lcWvNsu7dZwFYf4D5GSXcwdGm2g5371dHK23cdkx1KZDaFWcaKvR GaM+O1KdwEl2FNvxWadQ+5d90XL2zvvByPwDe7vaB8CUOVsSBoX81qBaDmi8wmK5 8gznAHn43N6AeIMogIyUMv2zpHL095d/NmHWXvD9UhU5ANGpSbAcmnzk46SI1A8o WVLscsSAo6aX9Efn9f/DCDipZM3S8q3JpHGrAlHzxDmCJMxuINx47Gur4JIdx3Gc ayHrEP9y8Obkixx8uUr0TKC3H6Gtb+rDr7mpcHWeeVez1al1E3uUoSKes5YP8eNp btaPXe3+NeX4nDOWEW1SFTgJtsAM1MAQuHNqYDLRBI2qWD41H7A7JX5tahpMdZd+ R4RSrOECYIepYBWs1S4V53d7Iwtqg3y5s5ybse8i4mNK05n5xWQ= =mso+ -----END PGP SIGNATURE----- --nextPart3234803.0WQXIW03uk--