Intended semantics of hygiene in R6RS

141 views
Skip to first unread message

Daphne Preston-Kendal

unread,
Sep 21, 2023, 6:13:21 PM9/21/23
to d...@cs.indiana.edu, mfl...@cs.utah.edu, an...@appsolutions.com, Will Clinger, Marc Nieper-Wißkirchen, scheme-re...@googlegroups.com
Dear R6RS editors,

I wondered if you might be willing to clear up a conflict over the interpretation and intent of the R6RS which has arisen in the course of revising its macro system for R7RS Large.

Marc Nieper-Wißkirchen discovered in 2021 that expanders such as André van Tonder’s have semantics that appear to disagree with those of the R6RS — or at least with all other known syntax-case expanders — when a transformer procedure incorporates into its output a syntax object which it is closed over, when that syntax object introduces an identifier. To wit, macros such as this have observably different behaviour (ignoring the phasing issue):

(define x-id #'x)

(define-syntax foo
(lambda (stx)
(syntax-case stx ()
((_ val)
#`(define #,x-id val)))))

(foo 1)
(foo 2)

According to the text of the R6RS, the renaming (marking/colouring/whatever name you give it) of introduced identifiers is associated with each macro transcription step. The foo macro introduces an identifier called x, and under the model specified by the report, this gets a fresh mark for each invocation of foo; this code defines two invisible variables called x. However, van Tonder’s expander performs renaming only once for the x identifier, within the process of evaluating the (syntax x) expression. (It does this to avoid walking over the whole output form and renaming everything after the transformer returns, since it does not wrap forms larger than individual identifiers.) So it attempts to define the same invisible identifier called x twice, which breaks.

I have to agree with Marc that the text of the R6RS implies that van Tonder’s expander breaks the hygiene condition for macros such as this. However, Will Clinger, when I asked him about this, asserted that Larceny’s expander (van Tonder’s) is in fact R6RS compliant and the R6RS spec was supposed to encompass and accommodate its semantics. I have found several indications in the historical record that the R6RS working group did, in fact, want to ensure that van Tonder’s general approach was valid, but not many references to the concrete details of observable differences that were known about at the time.

We have an issue thread where I have noted the changes that would need to be made (including to text which has thus far been taken directly from the R6RS) to fully accommodate the van Tonder model: <https://codeberg.org/scheme/r7rs/issues/167>. Marc has also posted some further examples there of macros which have different semantics under the two models.

So my questions are:
• Were you aware that van Tonder’s model could lead to this kind of difference in macro semantics?
• Do you consider Larceny’s expander to be compliant with the R6RS (according to what you intended the R6RS to allow, even if not according to its final text)?
and I guess secondarily:
• Is R6RS in error in some way? and
• Especially for Kent and Matthew as Scheme implementers: if you were writing R7RS, would you make changes to the R6RS definitions to accommodate this model?


Many thanks in advance for your help.
Best wishes


Daphne Preston-Kendal
Chair, Working Group 2 (R7RS Large)

Reply all
Reply to author
Forward
0 new messages