[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: Introductory material on hygienic macros in dr scheme
>>>>> "Matthew" == Matthew Flatt <mflatt@cs.utah.edu> writes:
Matthew> Quoting =?iso-8859-1?Q?Breannd=E1n =D3 Nuall=E1in?=:
>> >> > (let-syntax ((foo (syntax-rules () ((_ x) (bar x)))))
>> (define x 33))
>>
Matthew> In the "internal definitions" section:
Matthew> Definitions may occur at the beginning of a <body> (that
Matthew> is, the body of a lambda, let, let*, letrec, let-syntax,
Matthew> or letrec-syntax expression or that of a definition of an
Matthew> appropriate form). Such definitions are known as internal
Matthew> definitions as opposed to the top level definitions
Matthew> described above.
>>
>> But surely the above `define' should not be treated as
>> internal?
Matthew> Are we reading the above paragraph from R5RS differently,
Matthew> or are you suggesting that this part of R5RS is wrong? (I
Matthew> don't consider R5RS sacred, of course.)
As a matter of fact we are. At least, AFAICT we are.
My (incorrect) reading of R5RS was that the top-level expression
(let-syntax ((foo (syntax-rules () ((_ x) (bar x)))))
(define x 33))
becomes transformed to the top-level expression
(define x 33)
which is thus a top-level `define'.
I'm guessing that your (correct) reading of R5RS is that, in the
top-level expression,
(let-syntax ((foo (syntax-rules () ((_ x) (bar x)))))
(define x 33))
a `define' occurs within a `let-syntax' and so must be an internal
definition (at the start of a <body> as licensed by R5RS 5.2.2). In
that case it should transform to something like
(letrec ((x 33))
)
or
(let ()
(define x 33))
which are both illegal because of the empty bodies.
A legal case of your (correct) reading of R5RS would be something like
(let-syntax ((double (syntax-rules () ((_ n) (* 2 n)))))
(define x (double 3))
(+ x 4))
which should return 10. The binding for `x' should be local to the
body of the `let-syntax'.
This is where my reading about R5RS was wrong. I assumed that the
above form transformed into
(define x 6)
(+ x 4)
and that these forms were then placed at top-level.
Interestingly, Chez explicitly disagrees with R5RS:
"...let-syntax and letrec-syntax do not introduce local scopes as
they are specified to do in the Revised5 Report. This effect can
easily be achieved by inserting a let around the let-syntax or
letrec-syntax body." [Chez Scheme Users Guide, Section 4.1]
To be honest, I can't say whether I was misreading R5RS because I
never actually gave it much thought or whether the remnants of having
read CSUG a long time ago were still hanging around in my head.
Anyhow, I favour the Chez way. It allows one to use a local piece of
syntax to generate top-level forms. I can't think of a way to do that
with R5RS. So, in answer to your question, I guess I don't consider
R5RS sacred either.
I'm afraid I still don't get your point about the partial-expansion
mechanism of mzscheme though.
Breanndán