[plt-scheme] 299.11
The v299-tagged code in CVS for MzScheme and MrEd is now version 299.11.
(The exp-tagged code is still version 207.1.)
I've finally added `begin-for-syntax' and `require-for-template', which
let you modularize macro implementations more nicely.
Here's an example (adapted from the manual) showing a problem that
macro implementors often encounter:
(module et mzscheme
(define (mx) #'700)
(provide mx))
(module m mzscheme
(require-for-syntax et)
(define-syntax (onem stx) (mx))
(printf "~a~n" (onem))) ; prints 700 when run? No, ...
The use of `onem' doesn't work, because the `et' module has no bindings
that correspond to the run time of `m'. As a result, the compiler can't
make sense of the expression `700' that is generated by expanding
`(onem)'.
Before 299.10, the solution was to pass identifiers or other context
into `mx'. Now, the problem can be solved by simply adding a
`require-for-template' in `et':
(module et mzscheme
(require-for-template mzscheme) ; introduces a binding for the `#%datum'
; that lives in the future (relative to
; this module's run time)
(define (mx) #'700)
(provide mx))
(module m mzscheme
(require-for-syntax et)
(define-syntax (onem stx) (mx))
(printf "~a~n" (onem))) ; prints 700 when run
Alternatively, the implementor of `m' might not want another module.
Maybe the implementor merely wanted a helper `mx' to use in several
macros within `m'. In that case, the `begin-for-syntax' form offers a
better solution:
(module m mzscheme
(begin-for-syntax
(define (mx) #'700))
(define-syntax (onem stx) (mx))
(printf "~a~n" (onem))) ; prints 700 when run
Technically, `begin-for-syntax' is a macro that turns `define-values'
declarations into `define-values-for-syntax', and the latter is a core
form. The `begin-for-syntax' form also turns `require' into
`require-for-syntax' and `require-for-template' into `require'.
To complete the set, `define-for-syntax' expands into
`define-values-for-syntaxes'. So the above can also be written
(module m mzscheme
(define-for-syntax (mx) #'700)
(define-syntax (onem stx) (mx))
(printf "~a~n" (onem))) ; prints 700 when run
There's no `provide-for-syntax' or `require-for-syntax-for-syntax', so
there's also no `define-syntax-for-syntax' (which wouldn't be useful
without at least one of the other two). Similarly, it's no use to put
`begin-for-syntax' inside `begin-for-syntax'.
In the future, I may change MzScheme so that the core forms are
`begin-for-syntax' and `begin-for-template', and so they can be nested
arbitrarily. Then, a single module could contain definitions for
arbitrarily many different phases ("past" and "future").
But I think that we'll get pretty far with just `require-for-template'
and a restrictive `begin-for-syntax'. In any case, the current system
is a convenient stop on the way to the most general one.
----------------------------------------
Changes:
* New forms:
`require-for-template' [core form]
`define-values-for-syntax' [core form]
`define-for-syntax'
`begin-for-syntax'
* New procedures:
`local-transformer-expand'
`syntax-transforming?'
* `module-compiled-imports' now returns 3 values
* `identifier-binding' and `identifier-transformer-binding' return a
list of five items instead of four, in the case of a module-bound
identifier.
* Added an optional argument to `make-input-port' to support custom
line counting.
Temporary docs are in the usual place:
http://www.cs.utah.edu/~mflatt/tmp/mzscheme-doc.plt
http://www.cs.utah.edu/~mflatt/tmp/mzlib-doc.plt
http://www.cs.utah.edu/~mflatt/tmp/mred-doc.plt
Matthew