Discussion:
[Larceny-users] Bug in syntax-rules expander (R6RS semantics changed?)
David Rush
2009-09-25 12:16:28 UTC
Permalink
Hi y'all -

I have been deeply buried in wrapping various C APIs, and the
repetitive bytevector trickery has led me to a bit of macrology. Now,
this is my first time *ever* using LET-SYNTAX, so maybe I am getting
something wrong here, but using PLT 4.2.1 the following macro expands
as I (almost) expect

; -*- scheme -*-

(define-syntax define-wrapped-field
(syntax-rules ()
((define-wrapped-field (base field) spec0 spec+ ...)
(let-syntax
((wrap-spec
(syntax-rules ()
((wrap-spec (reader converter raw))
(define reader
(bvw-access-wrapper
(lambda (raw*) raw)
(lambda (init) (converter base 'field init)))
))
((wrap-spec (writer converter!))
(define writer
(bvw-update-wrapper
(lambda (bv val) (converter! base 'field bv val)))
))
)))
(begin
(wrap-spec spec0)
(wrap-spec spec+)
...
'de-nada
)))
))

; the above is used thusly

(define-wrapped-field (MQOD DynamicQName)
(mqod-dynamic-queue-name bvw-z-string "unknown")
(mqod-dynamic-queue-name bvw-z-string!)
)

; -*- end scheme -*-

The expansion under PLT becomes

(begin
(define mqod-object-name
(bvw-access-wrapper
(lambda (raw*) "unknown")
(lambda (init) (bvw-z-string MQOD 'ObjectName init))))
(define mqod-object-name!
(bvw-update-wrapper
(lambda (bv val) (bvw-z-string! MQOD 'ObjectName bv val))))
'de-nada))

which is totally expected. Larceny does comething else which looks
more or less like

((lambda ()
((lambda (\x2e;mqod-object-name\x7c;4 \x2e;mqod-object-name!\x7c;4)
(begin
(set! \x2e;mqod-object-name\x7c;4 ...)
...
'de-nada
))
(\x2e;unspecified)
(\x2e;unspecified))))

which would be fine *I suppose* except that it does *not* end up
defining the new bindings at toplevel (in R5RS mode, I have not tried
the other modes). Is this an actual bug?

Additionally, the inclusion of the expression 'de-nada appears to be a
new requirement (both in Larceny and PLT). I recall that using BEGIN
to encapsulate multiple toplevel defines was pretty much the standard
way to handle this kind of thing in R[45]RS. Is this really the way it
is supposed to work? That is quite a pernicious minor change, if it
is.

david rush
--
GPG Public key at http://cyber-rush.org/drr/gpg-public-key.txt
William D Clinger
2009-09-25 12:34:13 UTC
Permalink
Larceny's let-syntax conforms to the R5RS specification.
PLT's let-syntax implements a recommendation made at one
of the Scheme workshops some years ago: that let-syntax
not introduce a new scope.

The R6RS adopted the semantics implemented by PLT, and
it's a bug if Larceny doesn't support that semantics in
ERR5RS/R6RS modes.

Larceny's R5RS mode still supports the R5RS semantics,
however. We can't change that without breaking some old
code. I guess we could add an R5RS library that redefines
let-syntax, however.

Will
David Rush
2009-09-25 13:04:39 UTC
Permalink
Post by William D Clinger
Larceny's let-syntax conforms to the R5RS specification.
PLT's let-syntax implements a recommendation made at one
of the Scheme workshops some years ago: that let-syntax
not introduce a new scope.
The R6RS adopted the semantics implemented by PLT, and
Ah.
Post by William D Clinger
it's a bug if Larceny doesn't support that semantics in
ERR5RS/R6RS modes.
I haven't tried and don't much care, but it is good to know about
LET-SYNTAX in this context. Having never used it before (and
programmed around that in various ways) I didn't have any feel for
what to expect. In point of fact, I can see it making sense for
let-syntax working either way, depending on the emphasis on pragmatics
versus semantic clarity.
Post by William D Clinger
Larceny's R5RS mode still supports the R5RS semantics,
I will work within that then. If worse comes to worst I can always
move the syntax rules out of the let-syntax form and up to the
toplevel.

What about the requirement for an actual expression (as opposed to
just DEFINEs) within top-level BEGIN?

david rush
--
replied belatedly to the list...
Felix Klock
2009-09-25 16:36:45 UTC
Permalink
Post by David Rush
Post by William D Clinger
it's a bug if Larceny doesn't support that semantics in
ERR5RS/R6RS modes.
I haven't tried and don't much care, but it is good to know about
LET-SYNTAX in this context. Having never used it before (and
programmed around that in various ways) I didn't have any feel for
what to expect. In point of fact, I can see it making sense for
let-syntax working either way, depending on the emphasis on pragmatics
versus semantic clarity.
One can always get the effect specified by R5RS by wrapping a (let
() ...) around the (let-syntax ...), which could itself be specified
as a separate syntax-rules macro.

I do not think the other direction is possible, which is the best
argument I can see for making the change to the let-syntax scoping
semantics.

(When Will suggests making an R5RS library providing the alternative
let-syntax semantics, I assume he is thinking of using an explicitly-
renaming procedural macro to accomplish that task. But maybe I have
made an invalid inference.)

-Felix
William D Clinger
2009-09-25 17:47:48 UTC
Permalink
Post by Felix Klock
One can always get the effect specified by R5RS by wrapping a (let
() ...) around the (let-syntax ...), which could itself be specified
as a separate syntax-rules macro.
Good point. I'll log this as a bug, and think about
the backwards compatibility issues some more.

Will

Loading...