fix reference (restoring some text that was lost in the reference-manual rewrite) to describe the problem with macro-introduced bindings and the top level
svn: r16205
This commit is contained in:
parent
f7dc640f55
commit
954e850e20
|
@ -3,6 +3,9 @@
|
|||
(for-syntax mzscheme)
|
||||
"mz.ss")
|
||||
|
||||
@(define scheme-eval (make-base-eval))
|
||||
@(interaction-eval #:eval scheme-eval (require (for-syntax scheme/base)))
|
||||
|
||||
@;------------------------------------------------------------------------
|
||||
@title[#:tag "syntax-model"]{Syntax Model}
|
||||
|
||||
|
@ -447,7 +450,7 @@ core syntactic forms are encountered:
|
|||
right-hand-side expressions are also extended with the
|
||||
bindings.}
|
||||
|
||||
@item{Definitions in @scheme[internal-definition contexts] introduce
|
||||
@item{Definitions in @tech{internal-definition contexts} introduce
|
||||
bindings as described in @secref["intdef-body"].}
|
||||
|
||||
]
|
||||
|
@ -600,7 +603,7 @@ then expansion stops without adding the identifier.
|
|||
@;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
@subsection[#:tag "intdef-body"]{Internal Definitions}
|
||||
|
||||
An internal-definition context corresponds to a partial expansion step
|
||||
An @tech{internal-definition context} corresponds to a partial expansion step
|
||||
(see @secref["partial-expansion"]). A form that supports internal
|
||||
definitions starts by expanding its first form in an
|
||||
internal-definition context, but only partially. That is, it
|
||||
|
@ -692,6 +695,109 @@ module is attached to a namespace through
|
|||
are transitively attached, but instances are attached only at
|
||||
phases at or below the namespace's @tech{base phase}.
|
||||
|
||||
@;------------------------------------------------------------------------
|
||||
@subsection[#:tag "macro-introduced-bindings"]{Macro-Introduced Bindings}
|
||||
|
||||
When a top-level definition binds an identifier that originates from a
|
||||
macro expansion, the definition captures only uses of the identifier
|
||||
that are generated by the same expansion. This behavior is consistent
|
||||
with expansion in @tech{internal-definition contexts}, where the
|
||||
defined identifier turns into a fresh lexical binding.
|
||||
|
||||
@examples[
|
||||
(define-syntax def-and-use-of-x
|
||||
(syntax-rules ()
|
||||
[(def-and-use-of-x val)
|
||||
(code:comment @#,t{@scheme[x] below originates from this macro:})
|
||||
(begin (define x val) x)]))
|
||||
(define x 1)
|
||||
x
|
||||
(def-and-use-of-x 2)
|
||||
x
|
||||
|
||||
(define-syntax def-and-use
|
||||
(syntax-rules ()
|
||||
[(def-and-use x val)
|
||||
(code:comment @#,t{@scheme{x} below was provided by the macro use:})
|
||||
(begin (define x val) x)]))
|
||||
(def-and-use x 3)
|
||||
x
|
||||
]
|
||||
|
||||
For a top-level definition (outside of a module), the order of
|
||||
evaluation affects the binding of a generated definition for a
|
||||
generated identifier use. If the use precedes the definition, then
|
||||
the use refers to a non-generated binding, just as if the generated
|
||||
definition were not present. (No such dependency on order occurs
|
||||
within a module, since a module binding covers the entire module
|
||||
body.) To support the declaration of an identifier before its use,
|
||||
the @scheme[define-syntaxes] form avoids binding an identifier if the
|
||||
body of the @scheme[define-syntaxes] declaration produces zero
|
||||
results.
|
||||
|
||||
@examples[
|
||||
#:eval scheme-eval
|
||||
(define bucket-1 0)
|
||||
(define bucket-2 0)
|
||||
(define-syntax def-and-set!-use-of-x
|
||||
(syntax-rules ()
|
||||
[(def-and-set!-use-of-x val)
|
||||
(begin (set! bucket-1 x) (define x val) (set! bucket-2 x))]))
|
||||
(define x 1)
|
||||
(def-and-set!-use-of-x 2)
|
||||
x
|
||||
bucket-1
|
||||
bucket-2
|
||||
|
||||
(define-syntax defs-and-uses/fail
|
||||
(syntax-rules ()
|
||||
[(def-and-use)
|
||||
(begin
|
||||
(code:comment @#,t{Initial reference to @scheme[even] precedes definition:})
|
||||
(define (odd x) (if (zero? x) #f (even (sub1 x))))
|
||||
(define (even x) (if (zero? x) #t (odd (sub1 x))))
|
||||
(odd 17))]))
|
||||
(defs-and-uses/fail)
|
||||
|
||||
(define-syntax defs-and-uses
|
||||
(syntax-rules ()
|
||||
[(def-and-use)
|
||||
(begin
|
||||
(code:comment @#,t{Declare before definition via no-values @scheme[define-syntaxes]:})
|
||||
(define-syntaxes (odd even) (values))
|
||||
(define (odd x) (if (zero? x) #f (even (sub1 x))))
|
||||
(define (even x) (if (zero? x) #t (odd (sub1 x))))
|
||||
(odd 17))]))
|
||||
(defs-and-uses)
|
||||
]
|
||||
|
||||
Macro-generated \scheme{require} and \scheme{provide}
|
||||
clauses also introduce and reference generation-specific bindings:
|
||||
|
||||
@itemize[
|
||||
|
||||
@item{In @scheme[require], for a @scheme[_require-spec] of the form
|
||||
@scheme[(rename-in [_orig-id _bind-id])] or @scheme[(only-in
|
||||
.... [_orig-id _bind-id])], the @scheme[_bind-id] is bound only for
|
||||
uses of the identifier generated by the same macro expansion as
|
||||
@scheme[_bind-id]. In @scheme[require] for other
|
||||
@scheme[_require-spec]s, the generator of the @scheme[_require-spec]
|
||||
determines the scope of the bindings.}
|
||||
|
||||
@item{In @scheme[provide], for a @scheme[_provide-spec] of the form
|
||||
@scheme[_id], the exported identifier is the one that binds
|
||||
@scheme[_id] within the module in a generator-specific way, but the
|
||||
external name is the plain @scheme[_id]. The exceptions for
|
||||
@scheme[all-except-out] are similarly determined in a
|
||||
generator-specific way, as is the @scheme[_orig-id] binding of a
|
||||
@scheme[rename-out] form, but plain identifiers are used for the
|
||||
external names. For @scheme[all-defined-out], only identifiers with
|
||||
definitions having the same generator as the
|
||||
@scheme[(all-defined-out)] form are exported; the external name is
|
||||
the plain identifier from the definition.}
|
||||
|
||||
]
|
||||
|
||||
@;------------------------------------------------------------------------
|
||||
@section[#:tag "compilation-model"]{Compilation}
|
||||
|
||||
|
@ -860,3 +966,7 @@ When an inferred name is not available, but a source location is
|
|||
available, a name is constructed using the source location
|
||||
information. Inferred and property-assigned names are also available
|
||||
to syntax transformers, via @scheme[syntax-local-name].
|
||||
|
||||
@;----------------------------------------
|
||||
|
||||
@close-eval[scheme-eval]
|
||||
|
|
|
@ -1896,7 +1896,12 @@ expands to a definition of the first form where the @scheme[expr] is a
|
|||
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]. }
|
||||
@scheme[id].
|
||||
|
||||
When @scheme[expr] produces zero values for a top-level
|
||||
@scheme[define-syntaxes] (i.e., not in a module or internal-definition
|
||||
position), then the @scheme[id]s are effectively declared without
|
||||
binding; see @secref["macro-introduced-bindings"].
|
||||
|
||||
@defexamples[#:eval (syntax-eval)
|
||||
(define-syntaxes (foo1 foo2 foo3)
|
||||
|
@ -1915,7 +1920,7 @@ as @scheme[id]s, and each value is bound to the corresponding
|
|||
(foo1)
|
||||
(foo2)
|
||||
(foo3)
|
||||
]
|
||||
]}
|
||||
|
||||
@defform*[[(define-for-syntax id expr)
|
||||
(define-for-syntax (head args) body ...+)]]{
|
||||
|
|
Loading…
Reference in New Issue
Block a user