[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: Introductory material on hygienic macros in dr scheme
Quoting "Pierpaolo BERNARDI":
> I have a question myself on macros.
> mzscheme 200alpha9 gives:
>
> > (let-syntax ((foo
> (syntax-rules ()
> ((_ x) (bar x)))))
> (define x 33))
> begin (possibly implicit): no expression after a sequence of internal
> definitions in: ((define x 33))
>
> While the same expression works in Chez, where the (define x ...) is
> considered
> top level.
>
> From reading the r5rs is not clear to me which behaviour is correct.
In the "internal definitions" section:
Definitions may occur at the beginning of a <body> (that is, the body
of a lambda, let, let*, letrec, let-syntax, or letrec-syntax expression
or that of a definition of an appropriate form). Such definitions are
known as internal definitions as opposed to the top level definitions
described above.
So it seems the `define' above has to be treated as an internal
definition. But I wouldn't bet against there being a contradictory
statement elsewhere in R5RS.
I think the Chez convention probably doesn't work for PLT Scheme --
long explanation below.
Matthew
------------------------------
The Chez model seems to it interact confusingly (wrongly?) with
internal definitions. Here's the simplest example that I could manage:
(let-syntax ([ack
(syntax-rules ()
[(_) 'outer-ack])])
(letrec-syntax ([foo
(syntax-rules ()
((_ x) (define (x) (bar))))]
[bar
(syntax-rules ()
((_) (ack)))]) ;; <<<<<
(foo x))
(define (ack) 'inner-ack)
(x))
Which `ack' is the one marked by "<<<<<" ? If the `letrec-syntax'
expression produces a definition, then we have a two-definition
internal sequence, and `(define (ack) 5)' should bind the marked `ack'.
In other words, the above should be equivalent to
(let-syntax ([ack
(syntax-rules ()
[(_) 'outer-ack])])
(letrec ([x
(letrec-syntax ([bar
(syntax-rules ()
((_) (ack)))])
(lambda () (bar)))]
[ack (lambda () 'inner-ack)])
(x)))
However, Chez produces 'outer-ack for the first expression, and
'inner-ack for the second. So the marked `ack' is actually captured by
the outer `ack', not not the internal definition.
Scale this up to the problem of definitions with `class' and `unit',
consider that `define-struct' generates both normal and syntax
definitions, etc., and I believe the above pattern will soon cause
problems in practice.