more reference work on syntax transformers
svn: r6890
This commit is contained in:
parent
9a21c13be1
commit
dba44c0b1e
|
@ -14,4 +14,4 @@ called.
|
||||||
@include-section["stx-patterns.scrbl"]
|
@include-section["stx-patterns.scrbl"]
|
||||||
@include-section["stx-ops.scrbl"]
|
@include-section["stx-ops.scrbl"]
|
||||||
@include-section["stx-comp.scrbl"]
|
@include-section["stx-comp.scrbl"]
|
||||||
|
@include-section["stx-trans.scrbl"]
|
||||||
|
|
414
collects/scribblings/reference/stx-trans.scrbl
Normal file
414
collects/scribblings/reference/stx-trans.scrbl
Normal file
|
@ -0,0 +1,414 @@
|
||||||
|
#reader(lib "docreader.ss" "scribble")
|
||||||
|
@require["mz.ss"]
|
||||||
|
@require-for-syntax[mzscheme]
|
||||||
|
|
||||||
|
@define[(transform-time) @t{This procedure must be called during the
|
||||||
|
dynamic extent of a @tech{syntax transformer} application by the
|
||||||
|
expander, otherwise the @exnraise[exn:fail:contract].}]
|
||||||
|
|
||||||
|
|
||||||
|
@title[#:tag "mz:stxtrans"]{Syntax Transformers}
|
||||||
|
|
||||||
|
@defproc[(make-set!-transformer [proc (syntax? . -> . syntax?)])
|
||||||
|
set!-transformer?]{
|
||||||
|
|
||||||
|
Creates a @tech{syntax transformer} that cooperates with
|
||||||
|
@scheme[set!]. If the result of @scheme[make-set!-transformer] is
|
||||||
|
bound to @scheme[identifier] as a @tech{transformer binding}, then
|
||||||
|
@scheme[proc] is applied as a transformer when @scheme[identifier] is
|
||||||
|
used in an expression position, or when it is used as the target of a
|
||||||
|
@scheme[set!] assignment as @scheme[(set! identifier _expr)]. When the
|
||||||
|
identifier appears as a @scheme[set!] target, the entire @scheme[set!]
|
||||||
|
expression is provided to the transformer.
|
||||||
|
|
||||||
|
@examples[
|
||||||
|
(let ([x 1]
|
||||||
|
[y 2])
|
||||||
|
(let-syntax ([x (make-set!-transformer
|
||||||
|
(lambda (stx)
|
||||||
|
(syntax-case stx (set!)
|
||||||
|
(code:comment #, @t{Redirect mutation of x to y})
|
||||||
|
[(set! id v) (syntax (set! y v))]
|
||||||
|
(code:comment #, @t{Normal use of @scheme[x] really gets @scheme[x]})
|
||||||
|
[id (identifier? (syntax id)) (syntax x)])))])
|
||||||
|
(begin
|
||||||
|
(set! x 3)
|
||||||
|
(list x y))))
|
||||||
|
]}
|
||||||
|
|
||||||
|
|
||||||
|
@defproc[(set!-transformer? [v any/c]) boolean?]{
|
||||||
|
|
||||||
|
Returns @scheme[#t] if @scheme[v] is a value created by
|
||||||
|
@scheme[make-set!-transformer], @scheme[#f] otherwise.}
|
||||||
|
|
||||||
|
|
||||||
|
@defproc[(set!-transformer-procedure [transformer set!-transformer?])
|
||||||
|
(syntax? . -> . syntax?)]{
|
||||||
|
|
||||||
|
Returns the procedure that was passed to
|
||||||
|
@scheme[make-set!-transformer] to create @scheme[transformer].}
|
||||||
|
|
||||||
|
|
||||||
|
@defproc[(make-rename-transformer [id-stx syntax?])
|
||||||
|
rename-transformer?]{
|
||||||
|
|
||||||
|
Creates a value that, when used as a @tech{transformer binding},
|
||||||
|
inserts the identifier @scheme[id-stx] in place of whatever identifier
|
||||||
|
binds the transformer, including in non-application positions, and in
|
||||||
|
@scheme[set!] expressions. Such a transformer could be written
|
||||||
|
manually, but the one created by @scheme[make-rename-transformer]
|
||||||
|
cooperates specially with @scheme[syntax-local-value] (see below).}
|
||||||
|
|
||||||
|
|
||||||
|
@defproc[(rename-transformer? [v any/c]) boolean?]{
|
||||||
|
|
||||||
|
Returns @scheme[#t] if @scheme[v] is a value created by
|
||||||
|
@scheme[make-rename-transformer], @scheme[#f] otherwise.}
|
||||||
|
|
||||||
|
|
||||||
|
@defproc[(rename-transformer-target [transformer rename-transformer?])
|
||||||
|
syntax?]{
|
||||||
|
|
||||||
|
Returns the identifier passed to @scheme[make-rename-transformer] to
|
||||||
|
create @scheme[transformer].}
|
||||||
|
|
||||||
|
|
||||||
|
@defproc[(local-expand [stx syntax?]
|
||||||
|
[context-v (or/c (one-of 'expression 'top-level 'module
|
||||||
|
'module-begin)
|
||||||
|
list?)]
|
||||||
|
[stop-ids (or/c (listof identifier?) false/c)]
|
||||||
|
[intdef-ctx (or/c internal-definition-context?
|
||||||
|
false/c)
|
||||||
|
#f])
|
||||||
|
syntax?]{
|
||||||
|
|
||||||
|
Expands @scheme[stx] in the lexical context of the expression
|
||||||
|
currently being expanded. The @scheme[context-v] argument is used as
|
||||||
|
the result of @scheme[syntax-local-context] for immediate expansions;
|
||||||
|
for a particular @tech{internal-definition context}, generate a unique
|
||||||
|
value and @scheme[cons] it onto the current result of
|
||||||
|
@scheme[syntax-local-context] if it is a list.
|
||||||
|
|
||||||
|
When an identifier in @scheme[stop-ids] is encountered by the expander
|
||||||
|
in a subexpression, expansions stops for the subexpression. If
|
||||||
|
@scheme[#%app], @scheme[#%top], or @scheme[#%datum] (see
|
||||||
|
@secref["mz:stxspecial"]) appears in @scheme[stop-ids], then
|
||||||
|
application, top-level variable reference, and literal data
|
||||||
|
expressions without the respective explicit form are not wrapped with
|
||||||
|
the explicit form. If @scheme[stop-ids] is @scheme[#f] instead of a
|
||||||
|
list, then @scheme[stx] is expanded only as long as the outermost form
|
||||||
|
of @scheme[stx] is a macro (i.e., expansion does not proceed to
|
||||||
|
sub-expressions).
|
||||||
|
|
||||||
|
The optional @scheme[intdef-ctx] argument must be either @scheme[#f]
|
||||||
|
or the result of @scheme[syntax-local-make-definition-context]. In the
|
||||||
|
latter case, lexical information for internal definitions is added to
|
||||||
|
@scheme[stx] before it is expanded. The lexical information is also
|
||||||
|
added to the expansion result (because the expansion might introduce
|
||||||
|
bindings or references to internal-definition bindings).
|
||||||
|
|
||||||
|
Expansion of @scheme[stx] can use certificates for the expression
|
||||||
|
already being expanded (see @secref["mz:stxprotect"]) , and inactive
|
||||||
|
certificates associated with @scheme[stx] are activated for
|
||||||
|
@scheme[stx] (see @secref["mz:stxinactivecerts"]). Furthermore, if the
|
||||||
|
transformer is defined within a module (i.e., the current expansion
|
||||||
|
was triggered by a use of a module-defined identifier with a
|
||||||
|
@tech{transformer binding}) or if the current expression is being
|
||||||
|
expanded for the body of a module, then the expansion of @scheme[stx]
|
||||||
|
can use any identifier defined by the module.
|
||||||
|
|
||||||
|
@transform-time[]}
|
||||||
|
|
||||||
|
|
||||||
|
@defproc[(syntax-local-expand-expression [stx syntax?])
|
||||||
|
(values syntax? syntax?)]{
|
||||||
|
|
||||||
|
Like @scheme[local-expand] given @scheme['expression] and an empty
|
||||||
|
stop list, but with two results: a syntax object for the fully
|
||||||
|
expanded expression, and a syntax object whose content is opaque. The
|
||||||
|
latter can be used in place of the former (perhaps in a larger
|
||||||
|
expression produced by a macro transformer), and when the macro
|
||||||
|
expander encouters the opaque object, it substitutes the fully
|
||||||
|
expanded expression without re-expanding it; the
|
||||||
|
@exnraise[exn:fail:syntax] if the expansion context includes bindings
|
||||||
|
or marks that were not present for the original expansion, in which
|
||||||
|
case re-expansion might produce different results. Consistent use of
|
||||||
|
@scheme[syntax-local-expand-expression] and the opaque object thus
|
||||||
|
avoids quadratic expansion times when local expansions are nested.
|
||||||
|
|
||||||
|
@transform-time[]}
|
||||||
|
|
||||||
|
|
||||||
|
@defproc[(local-transformer-expand [stx syntax?]
|
||||||
|
[context-v (or/c (one-of 'expression 'top-level 'module
|
||||||
|
'module-begin)
|
||||||
|
list?)]
|
||||||
|
[stop-ids (or/c (listof identifier?) false/c)]
|
||||||
|
[intdef-ctx (or/c internal-definition-context?
|
||||||
|
false/c)
|
||||||
|
#f])
|
||||||
|
syntax?]{
|
||||||
|
|
||||||
|
Like @scheme[local-expand], but @scheme[stx] is expanded as a
|
||||||
|
transformer expression instead of a run-time expression.}
|
||||||
|
|
||||||
|
|
||||||
|
@defproc[(local-expand/capture-lifts [stx syntax?]
|
||||||
|
[context-v (or/c (one-of 'expression 'top-level 'module
|
||||||
|
'module-begin)
|
||||||
|
list?)]
|
||||||
|
[stop-ids (or/c (listof identifier?) false/c)]
|
||||||
|
[intdef-ctx (or/c internal-definition-context?
|
||||||
|
false/c)
|
||||||
|
#f])
|
||||||
|
syntax?]{
|
||||||
|
|
||||||
|
Like @scheme[local-expand], but if
|
||||||
|
@scheme[syntax-local-lift-expression] is called during the expansion
|
||||||
|
of @scheme[stx], the result is a syntax object that represents a
|
||||||
|
@scheme[begin] expression; lifted expression appear with their
|
||||||
|
identifiers in @scheme[define-values] forms, and the expansion of
|
||||||
|
@scheme[stx] is the last expression in the @scheme[begin]. The lifted
|
||||||
|
expressions are not expanded.}
|
||||||
|
|
||||||
|
@defproc[(local-transformer-expand/capture-lifts [stx syntax?]
|
||||||
|
[context-v (or/c (one-of 'expression 'top-level 'module
|
||||||
|
'module-begin)
|
||||||
|
list?)]
|
||||||
|
[stop-ids (or/c (listof identifier?) false/c)]
|
||||||
|
[intdef-ctx (or/c internal-definition-context?
|
||||||
|
false/c)
|
||||||
|
#f])
|
||||||
|
syntax?]{
|
||||||
|
|
||||||
|
Like @scheme[local-expand/capture-lifts], but @scheme[stx] is expanded
|
||||||
|
as a transformer expression instead of a run-time expression. Lifted
|
||||||
|
expressions are reported as @scheme[define-values] forms (in the
|
||||||
|
transformer environment).}
|
||||||
|
|
||||||
|
|
||||||
|
@defproc[(syntax-local-make-definition-context) internal-definition-context?]{
|
||||||
|
|
||||||
|
Creates an opaque internal-definition context value to be used with
|
||||||
|
@scheme[local-expand] and other functions. A transformer should create
|
||||||
|
one context for each set of internal definitions to be expanded, and
|
||||||
|
use it when expanding any form whose lexical context should include
|
||||||
|
the definitions. After discovering an internal @scheme[define-values]
|
||||||
|
or @scheme[define-syntaxes] form, use
|
||||||
|
@scheme[syntax-local-bind-syntaxes] to add bindings to the context.
|
||||||
|
|
||||||
|
@transform-time[]}
|
||||||
|
|
||||||
|
|
||||||
|
@defproc[(syntax-local-bind-syntaxes [id-list (listof identifier?)]
|
||||||
|
[expr (or/c syntax? false/c)]
|
||||||
|
[intdef-ctx internal-definition-context?])
|
||||||
|
void?]{
|
||||||
|
|
||||||
|
Binds each identifier in @scheme[id-list] within the
|
||||||
|
internal-definition context represented by @scheme[intdef-ctx], where
|
||||||
|
@scheme[intdef-ctx] is the result of
|
||||||
|
@scheme[syntax-local-make-definition-context]. Supply @scheme[#f] for
|
||||||
|
@scheme[expr] when the identifiers correspond to
|
||||||
|
@scheme[define-values] bindings, and supply a compile-time expression
|
||||||
|
when the identifiers correspond to @scheme[define-syntaxes] bindings;
|
||||||
|
the later case, the number of values produces by the expression should
|
||||||
|
match the number of identifiers, otherwise the
|
||||||
|
@exnraise[exn:fail:contract:arity].
|
||||||
|
|
||||||
|
@transform-time[]}
|
||||||
|
|
||||||
|
|
||||||
|
@defproc[(syntax-local-value [id-stx syntax?]
|
||||||
|
[failure-thunk (or/c (-> any) false/c)
|
||||||
|
#f]
|
||||||
|
[intdef-ctx (or/c internal-definition-context?
|
||||||
|
false/c)
|
||||||
|
#f])
|
||||||
|
any]{
|
||||||
|
|
||||||
|
Returns the @tech{transformer binding} value of @scheme[id-stx] in
|
||||||
|
either the context asscoiated with @scheme[intdef-ctx] (if not
|
||||||
|
@scheme[#f]) or the context of the expression being expanded (if
|
||||||
|
@scheme[indef-ctx] is @scheme[#f]). If @scheme[intdef-ctx] is
|
||||||
|
provided, it must be an extension of the context of the expression
|
||||||
|
being expanded.
|
||||||
|
|
||||||
|
If @scheme[id-stx] is bound to a rename transformer created with
|
||||||
|
@scheme[make-rename-transformer], @scheme[syntax-local-value]
|
||||||
|
effectively calls itself with the target of the rename and returns
|
||||||
|
that result, instead of the rename transformer.
|
||||||
|
|
||||||
|
If @scheme[id-stx] has no @tech{transformer binding} (via
|
||||||
|
@scheme[define-syntax], @scheme[let-syntax], etc.) in that
|
||||||
|
environment, the result is obtained by applying @scheme[failure-thunk]
|
||||||
|
if not @scheme[#f]. If @scheme[failure-thunk] is @scheme[false], the
|
||||||
|
@exnraise[exn:fail:contract].
|
||||||
|
|
||||||
|
Resolving @scheme[id-stx] can use certificates for the expression
|
||||||
|
being transformed (see @secref["mz:stxprotect"]) as well as inactive
|
||||||
|
certificates associated with @scheme[id-stx] (see
|
||||||
|
@secref["mz:stxinactivecerts"]). Furthermore, if the transformer is
|
||||||
|
defined within a module (i.e., the current transformation was
|
||||||
|
triggered by a use of a module-defined identifier) or if the current
|
||||||
|
expression is being expanded for the body of a module, then resolving
|
||||||
|
@scheme[id-stx] can access any identifier defined by the module.
|
||||||
|
|
||||||
|
@transform-time[]}
|
||||||
|
|
||||||
|
|
||||||
|
@defproc[(syntax-local-lift-expression [stx syntax?])
|
||||||
|
identifier?]{
|
||||||
|
|
||||||
|
Returns a fresh identifier, and cooperates with the @scheme[module],
|
||||||
|
@scheme[letrec-syntaxes+values], @scheme[define-syntaxes],
|
||||||
|
@scheme[begin-for-syntax], and top-level expanders to bind the
|
||||||
|
generated identifier to the expression @scheme[stx].
|
||||||
|
|
||||||
|
A run-time expression within a module is lifted to the module's top
|
||||||
|
level, just before the expression whose expansion requests the
|
||||||
|
lift. Similarly, a run-time expression outside of a module is lifted
|
||||||
|
to a top-level definition. A compile-time expression in a
|
||||||
|
@scheme[letrec-syntaxes+values] or @scheme[define-syntaxes] binding is
|
||||||
|
lifted to a @scheme[let] wrapper around the corresponding right-hand
|
||||||
|
side of the binding. A compile-time expression within
|
||||||
|
@scheme[begin-for-syntax] is lifted to a @scheme[define-for-syntax]
|
||||||
|
declaration just before the requesting expression.
|
||||||
|
|
||||||
|
Other syntactic forms can capture lifts by using
|
||||||
|
@scheme[local-expand/capture-lifts] or
|
||||||
|
@scheme[local-transformer-expand/capture-lifts].
|
||||||
|
|
||||||
|
@transform-time[]}
|
||||||
|
|
||||||
|
|
||||||
|
@defproc[(syntax-local-lift-module-end-declaration [stx syntax?])
|
||||||
|
void?]{
|
||||||
|
|
||||||
|
Cooperates with the @scheme[module] form to insert @scheme[stx] as
|
||||||
|
a top-level declaration at the end of the module currently being
|
||||||
|
expanded. If the current expression being transformed is not within a
|
||||||
|
@scheme[module] form, or if it is not a run-time expression, then the
|
||||||
|
@exnraise[exn:fail:contract]. If the current expression being
|
||||||
|
transformed is not in the module top-level, then @scheme[stx] is
|
||||||
|
eventually expanded in an expression context.
|
||||||
|
|
||||||
|
@transform-time[]}
|
||||||
|
|
||||||
|
|
||||||
|
@defproc[(syntax-local-name) (or/c symbol? false/c)]{
|
||||||
|
|
||||||
|
Returns an inferred name for the expression position being
|
||||||
|
transformed, or @scheme[#f] if no such name is available. See also
|
||||||
|
@secref["mz:infernames"].
|
||||||
|
|
||||||
|
@transform-time[]}
|
||||||
|
|
||||||
|
|
||||||
|
@defproc[(syntax-local-context)
|
||||||
|
(or/c (one-of 'expression 'top-level 'module 'module-begin)
|
||||||
|
list?)]{
|
||||||
|
|
||||||
|
Returns an indication of the context for expansion that triggered a
|
||||||
|
@tech{syntax transformer} call. See @secref["mz:expand-context-model"]
|
||||||
|
for more information on contexts.
|
||||||
|
|
||||||
|
The symbol results indicate that the expression is being expanded for
|
||||||
|
an @tech{expression context}, a @tech{top-level context}, a
|
||||||
|
@tech{module context}, or a @tech{module-begin context}.
|
||||||
|
|
||||||
|
A list result indicates expansion in an @tech{internal-definition
|
||||||
|
context}. The identity of the lists's first element (i.e., its
|
||||||
|
@scheme[eq?]ness) reflects the identity of the internal-definition
|
||||||
|
context; in particular two transformer expansions receive the same
|
||||||
|
first value if and only if they are invoked for the same
|
||||||
|
internal-definition context. Later values in the list similarly
|
||||||
|
identify internal-definition contexts that are still being expanded,
|
||||||
|
and that required the expansion of nested internal-definition
|
||||||
|
contexts.
|
||||||
|
|
||||||
|
@transform-time[]}
|
||||||
|
|
||||||
|
|
||||||
|
@defproc[(syntax-local-get-shadower [id-stx identifier?]) identifier?]{
|
||||||
|
|
||||||
|
Returns @scheme[id-stx] if no binding in the current expansion context
|
||||||
|
shadows @scheme[id-stx], if @scheme[id-stx] has no module bindings in
|
||||||
|
its lexical information, and if the current expansion context is not a
|
||||||
|
@tech{module context}.
|
||||||
|
|
||||||
|
If a binding of @scheme[inner-identifier] shadows @scheme[id-stx], the
|
||||||
|
result is the same as @scheme[(syntax-local-get-shadower
|
||||||
|
@scheme[inner-identifier])], except that it has the location and
|
||||||
|
properties of @scheme[id-stx].
|
||||||
|
|
||||||
|
Otherwise, the result is the same as @scheme[id-stx] with its module
|
||||||
|
bindings (if any) removed from its lexical information, and the
|
||||||
|
lexical information of the current @tech{module context} (if any)
|
||||||
|
added.
|
||||||
|
|
||||||
|
Thus, the result is an identifier corresponding to the innermost
|
||||||
|
shadowing of @scheme[id-stx] in the current context if its shadowed,
|
||||||
|
and a module-contextless version of @scheme[id-stx] otherwise.
|
||||||
|
|
||||||
|
@transform-time[]}
|
||||||
|
|
||||||
|
|
||||||
|
@defproc[(syntax-local-certifier [active? boolean? #f])
|
||||||
|
(syntax? (any/c (or/c procedure? false/c))
|
||||||
|
. opt-> . syntax?)]{
|
||||||
|
|
||||||
|
Returns a procedure that captures any certificates currently available
|
||||||
|
for @scheme[syntax-local-value] or @scheme[local-expand]. The
|
||||||
|
procedure accepts one to three arguments: @scheme[_stx] (required),
|
||||||
|
@scheme[_key] (optional), and @scheme[_intro] (optional). The
|
||||||
|
procedure's result is a syntax object like @scheme[stx], except that
|
||||||
|
it includes the captured certificates as inactive (see
|
||||||
|
@secref["mz:stxinactivecerts"]) if @scheme[active?] is @scheme[#f]
|
||||||
|
(the default) or active otherwise. If @scheme[key] is supplied and
|
||||||
|
not @scheme[#f], it is associated with each captured certificate for
|
||||||
|
later use through @scheme[syntax-recertify] (see
|
||||||
|
@secref["mz:stxtransfer"]). If @scheme[_intro] is supplied, and if it
|
||||||
|
is not @scheme[#f] (the default), then it must be a procedure created
|
||||||
|
by @scheme[make-syntax-introducer], in which case the certificate
|
||||||
|
applies only to parts of @scheme[stx] that are marked as introduced by
|
||||||
|
@scheme[_intro].
|
||||||
|
|
||||||
|
Supply @scheme[#t] for @scheme[active?] when the syntax to be
|
||||||
|
certified can be safely used in any context by any party, and where
|
||||||
|
access to the syntax object should not confer any additional
|
||||||
|
access. Supply @scheme[#f] for @scheme[active?] when the syntax to be
|
||||||
|
certified is not accessible to parties that might abuse the access
|
||||||
|
that the certificate provides, and when the certified syntax
|
||||||
|
eventually appears (via macro expansion) within a larger expression
|
||||||
|
from which it cannot be safely extracted by other parties.
|
||||||
|
|
||||||
|
@transform-time[]}
|
||||||
|
|
||||||
|
@defproc[(syntax-transforming?) boolean?]{
|
||||||
|
|
||||||
|
Returns @scheme[#t] during the dynamic extent of a @tech{syntax
|
||||||
|
transformer} application by the expander, @scheme[#f] otherwise.}
|
||||||
|
|
||||||
|
|
||||||
|
@defproc[(syntax-local-introduce [stx syntax?]) syntax?]{
|
||||||
|
|
||||||
|
Produces a syntax object that is like @scheme[stx], except that a
|
||||||
|
@tech{syntax mark} for the current expansion is added (possibly
|
||||||
|
canceling an existing mark in parts of @scheme[stx]). See
|
||||||
|
@secref["mz:transformer-model"] for information on @tech{syntax
|
||||||
|
marks}.
|
||||||
|
|
||||||
|
@transform-time[]}
|
||||||
|
|
||||||
|
|
||||||
|
@defproc[(make-syntax-introducer) (syntax? . -> . syntax?)]{
|
||||||
|
|
||||||
|
Produces a procedure that behaves like
|
||||||
|
@scheme[syntax-local-introduce], but using a fresh @tech{syntax
|
||||||
|
mark}. Multiple applications of the same
|
||||||
|
@scheme[make-syntax-introducer] result procedure use the same mark,
|
||||||
|
and different result procedures use distinct marks.}
|
||||||
|
|
|
@ -72,17 +72,25 @@ variable}. A hyperlinked @tech{identifier} @scheme[cons] is a
|
||||||
reference to a specific @tech{top-level variable}.
|
reference to a specific @tech{top-level variable}.
|
||||||
|
|
||||||
Every binding has a @deftech{phase level} in which it can be
|
Every binding has a @deftech{phase level} in which it can be
|
||||||
referenced, where a phase level corresponds to an integer. Phase level
|
referenced, where a @tech{phase level} corresponds to an
|
||||||
0 corresponds to the run time of the enclosing module (or the run time
|
integer. @tech{Phase level} 0 corresponds to the run time of the
|
||||||
of top-level expression); phase level 1 corresponds to the time during
|
enclosing module (or the run time of top-level expression). bindings
|
||||||
which the enclosing module (or top-level expression) is expanded;
|
in @tech{phase level} 0 constitute the @deftech{base environment}.
|
||||||
phase level -1 corresponds to the run time of a different module for
|
@tech{Phase level} 1 corresponds to the time during which the
|
||||||
which the enclosing module is imported for use at phase level 1
|
enclosing module (or top-level expression) is expanded; bindings in
|
||||||
(relative to the importing module). If an identifier has a @tech{local
|
@tech{phase level} 0 constitute the @deftech{transformer environment}.
|
||||||
binding}, then it is the same for all phase levels, though the
|
Phase level -1 corresponds to the run time of a different module for
|
||||||
reference is allowed only at a particular phase level. If an
|
which the enclosing module is imported for use at @tech{phase level} 1
|
||||||
identifier has a @tech{top-level binding} or @tech{module binding},
|
(relative to the importing module); bindings in @tech{phase level} -1
|
||||||
then it can have different such bindings in different phase levels.
|
constitute the @deftech{template environment}.
|
||||||
|
|
||||||
|
If an identifier has a @tech{local binding}, then it is the same for
|
||||||
|
all phase levels, though the reference is allowed only at a particular
|
||||||
|
phase level. Attempting to reference a @tech{local binding} in a
|
||||||
|
different @tech{phase level} than the binding's context produces a
|
||||||
|
syntax error. If an identifier has a @tech{top-level binding} or
|
||||||
|
@tech{module binding}, then it can have different such bindings in
|
||||||
|
different phase levels.
|
||||||
|
|
||||||
@;------------------------------------------------------------------------
|
@;------------------------------------------------------------------------
|
||||||
@section[#:tag "mz:stxobj-model"]{Syntax Objects}
|
@section[#:tag "mz:stxobj-model"]{Syntax Objects}
|
||||||
|
@ -161,7 +169,7 @@ A complete expansion produces a @tech{syntax object} matching the
|
||||||
following grammar:
|
following grammar:
|
||||||
|
|
||||||
@schemegrammar*[
|
@schemegrammar*[
|
||||||
#:literals (#%expression module #%plain-module-begin begin provide
|
#:literals (#%expression module #%module-begin begin provide
|
||||||
define-values define-syntaxes define-values-for-syntax
|
define-values define-syntaxes define-values-for-syntax
|
||||||
require require-for-syntax require-for-template
|
require require-for-syntax require-for-template
|
||||||
#%plain-lambda case-lambda if begin begin0 let-values letrec-values
|
#%plain-lambda case-lambda if begin begin0 let-values letrec-values
|
||||||
|
@ -170,7 +178,7 @@ following grammar:
|
||||||
[top-level-form general-top-level-form
|
[top-level-form general-top-level-form
|
||||||
(#%expression expr)
|
(#%expression expr)
|
||||||
(module id name-id
|
(module id name-id
|
||||||
(#%plain-module-begin
|
(#%module-begin
|
||||||
module-level-form ...))
|
module-level-form ...))
|
||||||
(begin top-level-form ...)]
|
(begin top-level-form ...)]
|
||||||
[module-level-form general-top-level-form
|
[module-level-form general-top-level-form
|
||||||
|
@ -219,20 +227,21 @@ one whose binding is @scheme[define-values]). In all cases,
|
||||||
identifiers above typeset as syntactic-form names refer to the
|
identifiers above typeset as syntactic-form names refer to the
|
||||||
bindings defined in @secref["mz:syntax"].
|
bindings defined in @secref["mz:syntax"].
|
||||||
|
|
||||||
Only @tech{phase levels} 0 and 1 are relevant for following the parse of a
|
Only @tech{phase levels} 0 and 1 are relevant for the parse of a
|
||||||
program (though the @scheme[_datum] in a @scheme[quote-syntax] form
|
program (though the @scheme[_datum] in a @scheme[quote-syntax] form
|
||||||
preserves its information for all phase levels). In particular, the
|
preserves its information for all @tech{phase level}s). In particular,
|
||||||
relevant phase level is 0, except for the @scheme[_expr]s in a
|
the relevant @tech{phase level} is 0, except for the @scheme[_expr]s
|
||||||
@scheme[define-syntaxes] @scheme[define-values-for-syntax], in which
|
in a @scheme[define-syntax], @scheme[define-syntaxes],
|
||||||
case the relevant phase is 1 (for which comparisons are made using
|
@scheme[define-for-syntax], or @scheme[define-values-for-syntax] form,
|
||||||
@scheme[free-transformer-identifier=?] instead of
|
in which case the relevant @tech{phase level} is 1 (for which
|
||||||
@scheme[free-identifier=?]).
|
comparisons are made using @scheme[free-transformer-identifier=?]
|
||||||
|
instead of @scheme[free-identifier=?]).
|
||||||
|
|
||||||
@;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
@;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
@subsection[#:tag "mz:expand-steps"]{Expansion Steps}
|
@subsection[#:tag "mz:expand-steps"]{Expansion Steps}
|
||||||
|
|
||||||
In a recursive expansion, each single step in expanding a @tech{syntax
|
In a recursive expansion, each single step in expanding a @tech{syntax
|
||||||
object} at a particular phase level depends on the immediate shape of
|
object} at a particular @tech{phase level} depends on the immediate shape of
|
||||||
the @tech{syntax object} being expanded:
|
the @tech{syntax object} being expanded:
|
||||||
|
|
||||||
@itemize{
|
@itemize{
|
||||||
|
@ -317,7 +326,7 @@ things:
|
||||||
}
|
}
|
||||||
|
|
||||||
@;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
@;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
@subsection{Expansion Context}
|
@subsection[#:tag "mz:expand-context-model"]{Expansion Context}
|
||||||
|
|
||||||
Each expansion step occurs in a particular @deftech{context}, and
|
Each expansion step occurs in a particular @deftech{context}, and
|
||||||
transformers and core syntactic forms may expand differently for
|
transformers and core syntactic forms may expand differently for
|
||||||
|
@ -362,28 +371,32 @@ core syntactic forms are encountered:
|
||||||
@item{When a @scheme[require] form is encountered at the top level or
|
@item{When a @scheme[require] form is encountered at the top level or
|
||||||
module level, all lexical information derived from the top
|
module level, all lexical information derived from the top
|
||||||
level or the specific module's level are extended with bindings
|
level or the specific module's level are extended with bindings
|
||||||
from the specified modules, and at the phase levels (normally
|
from the specified modules, and at the @tech{phase level}s
|
||||||
0) specified by the exporting modules.}
|
(normally 0) specified by the exporting modules.}
|
||||||
|
|
||||||
@item{When a @scheme[require-for-syntax] form is encountered at the
|
@item{When a @scheme[require-for-syntax] form is encountered at the
|
||||||
top level or module level, it is treated like @scheme[require],
|
top level or module level, it is treated like @scheme[require],
|
||||||
except that the phase level for all bindings is incremented by
|
except that the @tech{phase level} for all bindings is incremented by
|
||||||
1.}
|
1.}
|
||||||
|
|
||||||
@item{When a @scheme[require-for-template] form is encountered at the
|
@item{When a @scheme[require-for-template] form is encountered at the
|
||||||
top level or module level, it is treated like @scheme[require],
|
top level or module level, it is treated like @scheme[require],
|
||||||
except that the phase level for all bindings is decremented by
|
except that the @tech{phase level} for all bindings is decremented by
|
||||||
1.}
|
1.}
|
||||||
|
|
||||||
@item{When a @scheme[define-values] or @scheme[define-syntaxes] form
|
@item{When a @scheme[define], @scheme[define-values],
|
||||||
is encountered at the top level or module level, all lexical
|
@scheme[define-syntax], or @scheme[define-syntaxes] form is
|
||||||
|
encountered at the top level or module level, all lexical
|
||||||
information derived from the top level or the specific module's
|
information derived from the top level or the specific module's
|
||||||
level are extended with bindings for the specified identifiers
|
level is extended with bindings for the specified identifiers
|
||||||
at phase level 0.}
|
at @tech{phase level} 0 (i.e., the @tech{base environment} is
|
||||||
|
extended).}
|
||||||
|
|
||||||
@item{When a @scheme[define-values-for-syntax] form is encountered at
|
@item{When a @scheme[define-for-syntax] or
|
||||||
the top level or module level, bindings are introduced as for
|
@scheme[define-values-for-syntax] form is encountered at the
|
||||||
@scheme[define-values], but at phase level 1.}
|
top level or module level, bindings are introduced as for
|
||||||
|
@scheme[define-values], but at @tech{phase level} 1 (i.e., the
|
||||||
|
@tech{transformer environment} is extended).}
|
||||||
|
|
||||||
@item{When a @scheme[let-values] form is encountered, the body of the
|
@item{When a @scheme[let-values] form is encountered, the body of the
|
||||||
@scheme[let-values] form is extended (by creating new
|
@scheme[let-values] form is extended (by creating new
|
||||||
|
@ -391,7 +404,7 @@ core syntactic forms are encountered:
|
||||||
identifiers. The same bindings are added to the identifiers
|
identifiers. The same bindings are added to the identifiers
|
||||||
themselves, so that the identifiers in binding position are
|
themselves, so that the identifiers in binding position are
|
||||||
@scheme[bound-identifier=?] to uses in the fully expanded form,
|
@scheme[bound-identifier=?] to uses in the fully expanded form,
|
||||||
and so they are not @scheme[bound-identifier=?] t other
|
and so they are not @scheme[bound-identifier=?] to other
|
||||||
identifiers. The bindings are available for use at the
|
identifiers. The bindings are available for use at the
|
||||||
@tech{phase level} at which the @scheme[let-values] form is
|
@tech{phase level} at which the @scheme[let-values] form is
|
||||||
expanded.}
|
expanded.}
|
||||||
|
@ -432,19 +445,21 @@ expander encounters a @scheme[define-syntaxes] form, the binding that
|
||||||
it introduces for the defined identifiers is a @deftech{transformer
|
it introduces for the defined identifiers is a @deftech{transformer
|
||||||
binding}. The @tech{value} of the @tech{binding} exists at expansion
|
binding}. The @tech{value} of the @tech{binding} exists at expansion
|
||||||
time, rather than run time (though the two times can overlap), though
|
time, rather than run time (though the two times can overlap), though
|
||||||
the binding itself is introduced with phase level 0.
|
the binding itself is introduced with @tech{phase level} 0 (i.e., in
|
||||||
|
the @tech{base environment}).
|
||||||
|
|
||||||
The @deftech{value} for the binding is obtained by evaluating the
|
The @deftech{value} for the binding is obtained by evaluating the
|
||||||
expression in the @scheme[define-syntaxes] form. This expression must
|
expression in the @scheme[define-syntaxes] form. This expression must
|
||||||
be @tech{expand}ed (i.e. parsed) before it can be evaluated, and it is
|
be @tech{expand}ed (i.e. parsed) before it can be evaluated, and it is
|
||||||
expanded at @tech{phase level} 1 instead of @tech{phase level} 0.
|
expanded at @tech{phase level} 1 (i.e., in the @tech{transformer
|
||||||
|
environment}) instead of @tech{phase level} 0.
|
||||||
|
|
||||||
The if resulting @scheme[value] is a procedure of one argument, then
|
The if resulting @scheme[value] is a procedure of one argument or as
|
||||||
is it used as a @deftech{syntax transformer}. The procedure is
|
the result of @scheme[make-set!-transformer] on a procedure, then is
|
||||||
expected to accept a syntax object and return a syntax object. A use
|
it used as a @deftech{syntax transformer}. The procedure is expected
|
||||||
of the binding (at @tech{phase level} 0) triggers a call of the
|
to accept a syntax object and return a syntax object. A use of the
|
||||||
@tech{syntax transformer} by the expander; see
|
binding (at @tech{phase level} 0) triggers a call of the @tech{syntax
|
||||||
@secref["mz:expand-steps"].
|
transformer} by the expander; see @secref["mz:expand-steps"].
|
||||||
|
|
||||||
Before the expander passes a @tech{syntax object} to a transformer,
|
Before the expander passes a @tech{syntax object} to a transformer,
|
||||||
the @tech{syntax object} is extend with a @deftech{syntax mark} (that
|
the @tech{syntax object} is extend with a @deftech{syntax mark} (that
|
||||||
|
@ -493,16 +508,26 @@ that transformer @scheme[set!] expression. @tech{Assignment
|
||||||
transformers} are applied by @scheme[set!] in the same way as a normal
|
transformers} are applied by @scheme[set!] in the same way as a normal
|
||||||
transformer by the macro expander.
|
transformer by the macro expander.
|
||||||
|
|
||||||
|
The @scheme[make-rename-transformer] procedure creates a value that is
|
||||||
|
also handled specially by the expander and by @scheme[set!] as a
|
||||||
|
transformer binding's value. When @scheme[_id] is bound to a
|
||||||
|
@deftech{rename transformer} produced by
|
||||||
|
@scheme[make-rename-transformer], it is replaced with the identifier
|
||||||
|
passed to @scheme[make-rename-transformer]. Furthermore, the binding
|
||||||
|
is also specially handled by @scheme[syntax-local-value] as used by
|
||||||
|
@tech{syntax transformer}s.
|
||||||
|
|
||||||
The expander's handling of @scheme[letrec-values+syntaxes] is similar
|
The expander's handling of @scheme[letrec-values+syntaxes] is similar
|
||||||
to its handling of @scheme[define-syntaxes]. A
|
to its handling of @scheme[define-syntaxes]. A
|
||||||
@scheme[letrec-values+syntaxes] mist be expanded in an arbitrary phase
|
@scheme[letrec-values+syntaxes] mist be expanded in an arbitrary phase
|
||||||
level @math{n} (not just 0), in which case the expression for the
|
level @math{n} (not just 0), in which case the expression for the
|
||||||
@tech{transformer binding} is expanded at phase level @math{n+1}.
|
@tech{transformer binding} is expanded at @tech{phase level} @math{n+1}.
|
||||||
|
|
||||||
The expression in a @scheme[define-values-for-syntax] form is expanded
|
The expression in a @scheme[define-for-syntax] or
|
||||||
and evaluated in the same way as for @scheme[syntax]. However, the
|
@scheme[define-values-for-syntax] form is expanded and evaluated in
|
||||||
introduced binding is a normal binding at phase level 1 (not a
|
the same way as for @scheme[syntax]. However, the introduced binding
|
||||||
@tech{transformer binding} at phase level 0).
|
is a variable binding at @tech{phase level} 1 (not a @tech{transformer
|
||||||
|
binding} at @tech{phase level} 0).
|
||||||
|
|
||||||
@;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
@;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
@subsection[#:tag "mz:partial-expansion"]{Partial Expansion}
|
@subsection[#:tag "mz:partial-expansion"]{Partial Expansion}
|
||||||
|
@ -587,7 +612,8 @@ the required module to be merely visited at @tech{phase} 0, not
|
||||||
|
|
||||||
When the expander encounters @scheme[require-for-syntax], it
|
When the expander encounters @scheme[require-for-syntax], it
|
||||||
immediately instantiates the required module at @tech{phase} 1, in
|
immediately instantiates the required module at @tech{phase} 1, in
|
||||||
addition to adding bindings scheme @tech{phase level} 1.
|
addition to adding bindings scheme @tech{phase level} 1 (i.e., the
|
||||||
|
@tech{transformer enviornment}).
|
||||||
|
|
||||||
When the expander encounters @scheme[require] and
|
When the expander encounters @scheme[require] and
|
||||||
@scheme[require-for-syntax] within a @tech{module context}, the
|
@scheme[require-for-syntax] within a @tech{module context}, the
|
||||||
|
@ -626,8 +652,8 @@ namespace is also the starting point evaluating expanded code, where
|
||||||
the first step in evaluation is linking the code to specific module
|
the first step in evaluation is linking the code to specific module
|
||||||
instances and top-level variables.
|
instances and top-level variables.
|
||||||
|
|
||||||
For expansion purposes, a namespace maps each symbol in each phase
|
For expansion purposes, a namespace maps each symbol in each
|
||||||
level to one of three possible bindings:
|
@tech{phase level} to one of three possible bindings:
|
||||||
|
|
||||||
@itemize{
|
@itemize{
|
||||||
|
|
||||||
|
@ -648,18 +674,21 @@ variable (in addition to installing a value into the variable).
|
||||||
|
|
||||||
A namespace also has a @deftech{module registry} that maps module
|
A namespace also has a @deftech{module registry} that maps module
|
||||||
names to module declarations (see @secref["mz:module-eval-model"]).
|
names to module declarations (see @secref["mz:module-eval-model"]).
|
||||||
This registry is shared by all phase levels, though instances of
|
This registry is shared by all @tech{phase level}s.
|
||||||
declared modules are not.
|
|
||||||
|
|
||||||
For evaluation, each namespace encapsulates a distinct set of
|
For evaluation, each namespace encapsulates a distinct set of
|
||||||
top-level variables, as well as a potentially distinct set of module
|
top-level variables, as well as a potentially distinct set of module
|
||||||
instances in each phase. After a namespace is created, module
|
instances in each @tech{phase}. That is, even though module
|
||||||
instances from existing namespaces can be attached to the new
|
declarations are shared for all @tech{phase levels}, module instances
|
||||||
namespace. In terms of the evaluation model, top-level variables from
|
are distinct for each @tech{phase}.
|
||||||
different namespaces essentially correspond to definitions with
|
|
||||||
different prefixes. Furthermore, the first step in evaluating any
|
After a namespace is created, module instances from existing
|
||||||
compiled expression is to link its top-level variable and module-level
|
namespaces can be attached to the new namespace. In terms of the
|
||||||
variable references to specific variables in the namespace.
|
evaluation model, top-level variables from different namespaces
|
||||||
|
essentially correspond to definitions with different prefixes.
|
||||||
|
Furthermore, the first step in evaluating any compiled expression is
|
||||||
|
to link its top-level variable and module-level variable references to
|
||||||
|
specific variables in the namespace.
|
||||||
|
|
||||||
At all times during evaluation, some namespace is designated as the
|
At all times during evaluation, some namespace is designated as the
|
||||||
@deftech{current namespace}. The current namespace has no particular
|
@deftech{current namespace}. The current namespace has no particular
|
||||||
|
|
|
@ -356,7 +356,7 @@ Like @scheme[lambda], but without support for keyword or optional arguments.
|
||||||
}
|
}
|
||||||
|
|
||||||
@;------------------------------------------------------------------------
|
@;------------------------------------------------------------------------
|
||||||
@section[#:tag "mz:let"]{Local Binding: @scheme[let], @scheme[let*], and @scheme[letrec]}
|
@section[#:tag "mz:let"]{Local Binding: @scheme[let], @scheme[let*], @scheme[letrec], ...}
|
||||||
|
|
||||||
@guideintro["guide:let"]{local binding}
|
@guideintro["guide:let"]{local binding}
|
||||||
|
|
||||||
|
@ -590,7 +590,7 @@ position with respect to the original @scheme[or] form.
|
||||||
]}
|
]}
|
||||||
|
|
||||||
@;------------------------------------------------------------------------
|
@;------------------------------------------------------------------------
|
||||||
@section[#:tag "mz:define"]{Definitions: @scheme[define] and @scheme[define-values]}
|
@section[#:tag "mz:define"]{Definitions: @scheme[define], @scheme[define-syntax], ...}
|
||||||
|
|
||||||
@guideintro["guide:define"]{definitions}
|
@guideintro["guide:define"]{definitions}
|
||||||
|
|
||||||
|
@ -660,8 +660,45 @@ z
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@defform*[[(define-syntax id expr)
|
||||||
|
(define-syntax (head args) body ...+)]]{
|
||||||
|
|
||||||
|
The first form creates a @tech{transformer binding} (see
|
||||||
|
@secref["mz:transformer-model"]) of @scheme[id] with the value of
|
||||||
|
@scheme[expr], which is an expression at @tech{phase level} 1 relative
|
||||||
|
to the surrounding context. (See @secref["mz:id-model"] for
|
||||||
|
information on @tech{phase levels}.)
|
||||||
|
|
||||||
|
The second form is a shorthand the same as for @scheme[define]; it
|
||||||
|
expands to a definition of the first form where the @scheme[expr] is a
|
||||||
|
@scheme[lambda] form.}
|
||||||
|
|
||||||
|
|
||||||
|
@defform[(define-syntaxes (id ...) expr)]{
|
||||||
|
|
||||||
|
Like @scheme[define-syntax], but creates a @tech{transformer binding}
|
||||||
|
for each @scheme[id]. The @scheme[expr] should produce as many values
|
||||||
|
as @scheme[id]s, and each value is bound to the corresponding
|
||||||
|
@scheme[id].}
|
||||||
|
|
||||||
|
|
||||||
|
@defform*[[(define-for-syntax id expr)
|
||||||
|
(define-for-syntax (head args) body ...+)]]{
|
||||||
|
|
||||||
|
Like @scheme[define], except that the binding is at @tech{phase level}
|
||||||
|
1 instead of @tech{phase level} 0 relative to its context. The
|
||||||
|
expression for the binding is also at @tech{phase level} 1. (See
|
||||||
|
@secref["mz:id-model"] for information on @tech{phase levels}.)}
|
||||||
|
|
||||||
|
@defform[(define-values-for-syntax (id ...) expr)]{
|
||||||
|
|
||||||
|
Like @scheme[define-for-syntax], but @scheme[expr] must produce as
|
||||||
|
many value as supplied @scheme[id]s, and all of the @scheme[id]s are
|
||||||
|
bound (at @tech{phase level} 1).}
|
||||||
|
|
||||||
@;------------------------------------------------------------------------
|
@;------------------------------------------------------------------------
|
||||||
@section[#:tag "mz:begin"]{Sequencing: @scheme[begin] and @scheme[begin0]}
|
@section[#:tag "mz:begin"]{Sequencing: @scheme[begin], @scheme[begin0], and @scheme[begin-for-syntax]}
|
||||||
|
|
||||||
@guideintro["guide:begin"]{@scheme[begin] and @scheme[begin0]}
|
@guideintro["guide:begin"]{@scheme[begin] and @scheme[begin0]}
|
||||||
|
|
||||||
|
@ -706,6 +743,34 @@ in tail position only if no @scheme[body]s are present.
|
||||||
(printf "hi\n"))
|
(printf "hi\n"))
|
||||||
]}
|
]}
|
||||||
|
|
||||||
|
@defform[(begin-for-syntax form ...)]{
|
||||||
|
|
||||||
|
Allowed only in a @tech{top-level context} or @tech{module context}.
|
||||||
|
Each @scheme[form] is partially expanded (see
|
||||||
|
@secref["mz:partial-expansion"]) to determine one of the following
|
||||||
|
classifications:
|
||||||
|
|
||||||
|
@itemize{
|
||||||
|
|
||||||
|
@item{@scheme[define] or @scheme[define-values] form: converted to
|
||||||
|
a @scheme[define-for-syntax] form.}
|
||||||
|
|
||||||
|
@item{@scheme[require] form: converted to a
|
||||||
|
@scheme[require-for-syntax] form.}
|
||||||
|
|
||||||
|
@item{@scheme[require-for-template] form: converted to a
|
||||||
|
@scheme[require].}
|
||||||
|
|
||||||
|
@item{expression form @scheme[_expr]: converted to
|
||||||
|
@scheme[(define-values () (begin _expr (values)))], which
|
||||||
|
effectively evaluates the expression at expansion time and, in
|
||||||
|
the case of a @tech{module context}, preserves the expression
|
||||||
|
for future @tech{visit}s of the module.}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
@;------------------------------------------------------------------------
|
@;------------------------------------------------------------------------
|
||||||
@section[#:tag "mz:when+unless"]{Guarded Evaluation: @scheme[when] and @scheme[unless]}
|
@section[#:tag "mz:when+unless"]{Guarded Evaluation: @scheme[when] and @scheme[unless]}
|
||||||
|
|
||||||
|
@ -745,10 +810,14 @@ Equivalent to @scheme[(when (not test-expr) expr ...)].
|
||||||
|
|
||||||
@defform[(set! id expr)]{
|
@defform[(set! id expr)]{
|
||||||
|
|
||||||
If @scheme[id] is bound as syntax to an @tech{assignment transformer},
|
If @scheme[id] has a @tech{transformer bounding} to an
|
||||||
as produced by @scheme[make-set!-transformer], then this form is
|
@tech{assignment transformer}, as produced by
|
||||||
expanded by calling the assignment transformer with the full
|
@scheme[make-set!-transformer], then this form is expanded by calling
|
||||||
expressions.
|
the assignment transformer with the full expressions. If @scheme[id]
|
||||||
|
has a @tech{transformer bounding} to a @tech{rename transformer} as
|
||||||
|
produced by @scheme[make-rename-transformer], then this form is
|
||||||
|
expanded by replacing @scheme[id] with the one provided to
|
||||||
|
@scheme[make-rename-transformer].
|
||||||
|
|
||||||
Otherwise, evaluates @scheme[expr] and installs the result into the
|
Otherwise, evaluates @scheme[expr] and installs the result into the
|
||||||
location for @scheme[id], which must be bound as a local variable or
|
location for @scheme[id], which must be bound as a local variable or
|
||||||
|
@ -830,7 +899,7 @@ information} and source-location information attached to
|
||||||
}
|
}
|
||||||
|
|
||||||
@;------------------------------------------------------------------------
|
@;------------------------------------------------------------------------
|
||||||
@section[#:tag "mz:module"]{Modules: @scheme[module]}
|
@section[#:tag "mz:module"]{Modules: @scheme[module], ...}
|
||||||
|
|
||||||
@defform[(module id require-spec form ...)]{
|
@defform[(module id require-spec form ...)]{
|
||||||
|
|
||||||
|
@ -843,16 +912,16 @@ is treated like a @scheme[(require require-spec)] prefix on
|
||||||
|
|
||||||
If a single @scheme[form] is provided, then it is partially expanded
|
If a single @scheme[form] is provided, then it is partially expanded
|
||||||
in a @tech{module-begin context}. If the expansion leads to
|
in a @tech{module-begin context}. If the expansion leads to
|
||||||
@scheme[#%plain-module-begin], then the body of the
|
@scheme[#%module-begin], then the body of the @scheme[#%module-begin]
|
||||||
@scheme[#%plain-module-begin] is the body of the module. If partial
|
is the body of the module. If partial expansion leads to any other
|
||||||
expansion leads to any other primitive form, then the form is wrapped
|
primitive form, then the form is wrapped with
|
||||||
with @schemeidfont{#%module-begin} using the lexical context of the
|
@schemeidfont{#%module-begin} using the lexical context of the module
|
||||||
module body; this identifier must be bound by the initial
|
body; this identifier must be bound by the initial
|
||||||
@scheme[require-spec] import, and its expansion must produce a
|
@scheme[require-spec] import, and its expansion must produce a
|
||||||
@scheme[#%plain-module-begin] to supply the module body. Finally, if
|
@scheme[#%module-begin] to supply the module body. Finally, if
|
||||||
multiple @scheme[form]s are provided, they are wrapped with
|
multiple @scheme[form]s are provided, they are wrapped with
|
||||||
@schemeidfont{#%module-begin}, as in the case where a single
|
@schemeidfont{#%module-begin}, as in the case where a single
|
||||||
@scheme[form] does not expand to @scheme[#%plain-module-begin].
|
@scheme[form] does not expand to @scheme[#%module-begin].
|
||||||
|
|
||||||
Each @scheme[form] is partially expanded (see
|
Each @scheme[form] is partially expanded (see
|
||||||
@secref["mz:partial-expansion"]) in a @tech{module context}. Further
|
@secref["mz:partial-expansion"]) in a @tech{module context}. Further
|
||||||
|
@ -919,6 +988,11 @@ error, just like accessing an undefined global variable.
|
||||||
|
|
||||||
See also @secref["mz:module-eval-model"] and @secref["mz:mod-parse"].}
|
See also @secref["mz:module-eval-model"] and @secref["mz:mod-parse"].}
|
||||||
|
|
||||||
|
@defform[(#%module-begin form ...)]{
|
||||||
|
|
||||||
|
Legal only in a @tech{module begin context}, and handled by the
|
||||||
|
@scheme[module] form.}
|
||||||
|
|
||||||
@;------------------------------------------------------------------------
|
@;------------------------------------------------------------------------
|
||||||
@section[#:tag "mz:require"]{Importing: @scheme[require], @scheme[require-for-syntax], @scheme[require-for-template]}
|
@section[#:tag "mz:require"]{Importing: @scheme[require], @scheme[require-for-syntax], @scheme[require-for-template]}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue
Block a user