racket/pkgs/racket-doc/scribblings/reference/namespaces.scrbl
Matthew Flatt c6802ed107 namespace-attach-module: fix handling of for-template
The handling of `for-template` imports by `namespace-attach-module`
didn't match the docs. The actual handling was to refrain from
attaching instances of a phase-0 module if the instance was reachable
only through a `for-template`. The rationale had to do with such
modules instances being created only through instantiation of
phase-1 modules, and phase-1 module instances aren't attached;
it doesn't work well that way, though, when different modules
are attached with intervening `namespace-require`s on the target
namespace.

The change includes a documentation correction. Previously and still,
only modules at the same phase as the attached module (as opposed to
the same phase or less) are instantiated in the target namespace.

Closes PR 14938
2015-01-18 11:19:49 -07:00

462 lines
18 KiB
Racket

#lang scribble/doc
@(require "mz.rkt")
@title[#:tag "Namespaces"]{Namespaces}
See @secref["namespace-model"] for basic information on the
@tech{namespace} model.
A new @tech{namespace} is created with procedures like
@racket[make-empty-namespace], and @racket[make-base-namespace], which
return a first-class namespace value. A namespace is used by setting
the @racket[current-namespace] parameter value, or by providing the
namespace to procedures such as @racket[eval] and
@racket[eval-syntax].
@defproc[(namespace? [v any/c]) boolean?]{
Returns @racket[#t] if @racket[v] is a namespace value, @racket[#f]
otherwise.}
@defproc[(make-empty-namespace) namespace?]{
Creates a new namespace that is empty, and whose @tech{module
registry} contains no mappings. The namespace's @tech{base phase} is
the same as the @tech{base phase} of the @tech{current
namespace}. Attach modules from an existing namespace to the new one
with @racket[namespace-attach-module].}
@defproc[(make-base-empty-namespace) namespace?]{
Creates a new empty namespace, but with @racketmodname[racket/base]
attached. The namespace's @tech{base phase} is the same as the
@tech{phase} in which the @racket[make-base-empty-namespace]
function was created.}
@defproc[(make-base-namespace) namespace?]{
Creates a new namespace with @racketmodname[racket/base] attached and
@racket[require]d into the top-level environment. The namespace's
@tech{base phase} is the same as the @tech{phase} in which the
@racket[make-base-namespace] function was created.}
@defform[(define-namespace-anchor id)]{
Binds @racket[id] to a namespace anchor that can be used with
@racket[namespace-anchor->empty-namespace] and
@racket[namespace-anchor->namespace].
This form can be used only in a @tech{top-level context} or in a
@tech{module-context}.}
@defproc[(namespace-anchor? [v any/c]) boolean?]{
Returns @racket[#t] if @racket[v] is a namespace-anchor value,
@racket[#f] otherwise.}
@defproc[(namespace-anchor->empty-namespace [a namespace-anchor?]) namespace?]{
Returns an empty namespace that shares a @tech{module registry} with
the source of the anchor, and whose @tech{base phase} is the
@tech{phase} in which the anchor was created.
If the anchor is from a @racket[define-namespace-anchor] form in a
module context, then the source is the namespace in which the
containing module is instantiated. If the anchor is from a
@racket[define-namespace-anchor] form in a top-level content, then the
source is the namespace in which the anchor definition was evaluated.}
@defproc[(namespace-anchor->namespace [a namespace-anchor?]) namespace?]{
Returns a namespace corresponding to the source of the anchor.
If the anchor is from a @racket[define-namespace-anchor] form in a
module context, then the result is a namespace for the module's body
in the anchor's phase. The result is the same as a namespace obtained
via @racket[module->namespace].
If the anchor is from a @racket[define-namespace-anchor] form in a
top-level content, then the result is the namespace in which the
anchor definition was evaluated.}
@defparam[current-namespace n namespace?]{
A @tech{parameter} that determines the @techlink{current namespace}.}
@defproc[(namespace-symbol->identifier [sym symbol?]) identifier?]{
Similar to @racket[datum->syntax] restricted to symbols. The
@tech{lexical information} of the resulting identifier corresponds to
the top-level environment of the current namespace; the identifier has
no source location or properties.}
@defproc[(namespace-base-phase [namespace namespace? (current-namespace)]) exact-integer?]{
Returns the @tech{base phase} of @racket[namespace].}
@defproc[(namespace-module-identifier [where (or/c namespace? exact-integer? #f)
(current-namespace)])
identifier?]{
Returns an identifier whose binding is @racket[module] in the
@tech{base phase} of @racket[where] if it is a namespace, or in the
@racket[where] @tech{phase level} otherwise.
The @tech{lexical information} of the identifier includes bindings (in
the same @tech{phase level}) for all syntactic forms that appear in
fully expanded code (see @secref["fully-expanded"]), but using the
name reported by the second element of @racket[identifier-binding] for
the binding; the @tech{lexical information} may also include other
bindings.}
@defproc[(namespace-variable-value [sym symbol?]
[use-mapping? any/c #t]
[failure-thunk (or/c (-> any) #f) #f]
[namespace namespace? (current-namespace)])
any]{
Returns a value for @racket[sym] in @racket[namespace], using
@racket[namespace]'s @tech{base phase}. The returned value depends on
@racket[use-mapping?]:
@itemize[
@item{If @racket[use-mapping?] is true (the default), and if
@racket[sym] maps to a top-level variable or an imported variable
(see @secref["namespace-model"]), then the result is the same as
evaluating @racket[sym] as an expression. If @racket[sym] maps to
syntax or imported syntax, then @racket[failure-thunk] is called or
the @exnraise[exn:fail:syntax]. If @racket[sym] is mapped to an
undefined variable or an uninitialized module variable, then
@racket[failure-thunk] is called or the
@exnraise[exn:fail:contract:variable].}
@item{If @racket[use-mapping?] is @racket[#f], the namespace's
syntax and import mappings are ignored. Instead, the value of the
top-level variable named @racket[sym] in namespace is returned. If
the variable is undefined, then @racket[failure-thunk] is called or
the @exnraise[exn:fail:contract:variable].}
]
If @racket[failure-thunk] is not @racket[#f],
@racket[namespace-variable-value] calls @racket[failure-thunk] to
produce the return value in place of raising an
@racket[exn:fail:contract:variable] or @racket[exn:fail:syntax]
exception.}
@defproc[(namespace-set-variable-value! [sym symbol?]
[v any/c]
[map? any/c #f]
[namespace namespace? (current-namespace)])
void?]{
Sets the value of @racket[sym] in the top-level environment of
@racket[namespace] in the @tech{base phase}, defining @racket[sym] if
it is not already defined.
If @racket[map?] is supplied as true, then the namespace's
@tech{identifier} mapping is also adjusted (see
@secref["namespace-model"]) in the @tech{phase level} corresponding to
the @tech{base phase}, so that @racket[sym] maps to the variable.}
@defproc[(namespace-undefine-variable! [sym symbol?]
[namespace namespace? (current-namespace)])
void?]{
Removes the @racket[sym] variable, if any, in the top-level
environment of @racket[namespace] in its @tech{base phase}. The
namespace's @tech{identifier} mapping (see @secref["namespace-model"])
is unaffected.}
@defproc[(namespace-mapped-symbols [namespace namespace? (current-namespace)])
(listof symbol?)]{
Returns a list of all symbols that are mapped to variables, syntax,
and imports in @racket[namespace] for the @tech{phase level}
corresponding to the @tech{namespace}'s @tech{base phase}.}
@defproc[(namespace-require [quoted-raw-require-spec any/c])
void?]{
Performs the import corresponding to @racket[quoted-raw-require-spec]
in the top-level environment of the current namespace, like a
top-level @racket[#%require]. The @racket[quoted-raw-require-spec]
argument must be a datum that corresponds to a quoted
@racket[_raw-require-spec] for @racket[#%require], which includes
module paths.
Module paths in @racket[quoted-raw-require-spec] are resolved with respect
to @racket[current-load-relative-directory] or
@racket[current-directory] (if the former is @racket[#f]), even if the
current namespace corresponds to a module body.}
@defproc[(namespace-require/copy [quoted-raw-require-spec any/c])
void?]{
Like @racket[namespace-require] for syntax exported from the module,
but exported variables at the namespace's @tech{base phase} are
treated differently: the export's current value is copied to a
top-level variable in the current namespace.}
@defproc[(namespace-require/constant [quoted-raw-require-spec any/c])
void?]{
Like @racket[namespace-require], but for each exported variable at the
@tech{namespace}'s @tech{base phase}, the export's value is copied to
a corresponding top-level variable that is made immutable. Despite
setting the top-level variable, the corresponding identifier is bound
as imported.}
@defproc[(namespace-require/expansion-time [quoted-raw-require-spec any/c])
void?]{
Like @racket[namespace-require], but only the transformer part of the
module is executed relative to the @tech{namespace}'s @tech{base
phase}; that is, the module is merely @tech{visit}ed, and not
@tech{instantiate}d (see @secref["mod-parse"]). If the required module
has not been instantiated before, the module's variables remain
undefined.}
@defproc[(namespace-attach-module [src-namespace namespace?]
[modname module-path?]
[dest-namespace namespace? (current-namespace)])
void?]{
Attaches the instantiated module named by @racket[modname] in
@racket[src-namespace] (at its @tech{base phase}) to the @tech{module
registry} of @racket[dest-namespace].
In addition to @racket[modname], every module that it imports
(directly or indirectly) is also recorded in the current namespace's
@tech{module registry}, and instances at the same @tech{phase}
are also attached to @racket[dest-namespace] (while
@tech{visits} at the module's phase and instances at higher or lower phases are
not attached, nor even made @tech{available} for on-demand
@tech{visits}). The inspector of the module invocation in
@racket[dest-namespace] is the same as inspector of the invocation in
@racket[src-namespace].
If @racket[modname] is not a symbol, the current module name resolver
is called to resolve the path, but no module is loaded; the resolved
form of @racket[modname] is used as the module name in
@racket[dest-namespace].
If @racket[modname] refers to a submodule or a module with submodules,
unless the module was loaded from bytecode (i.e., a @filepath{.zo}
file) independently from submodules within the same top-level module,
then declarations for all submodules within the module's top-level
module are also attached to @racket[dest-namespace].
If @racket[modname] does not refer to an @tech{instantiate}d module in
@racket[src-namespace], or if the name of any module to be attached
already has a different declaration or same-@tech{phase} instance in
@racket[dest-namespace], then the @exnraise[exn:fail:contract].
If @racket[src-namespace] and @racket[dest-namespace] do not have the
same @tech{base phase}, then the @exnraise[exn:fail:contract].}
@defproc[(namespace-attach-module-declaration [src-namespace namespace?]
[modname module-path?]
[dest-namespace namespace? (current-namespace)])
void?]{
Like @racket[namespace-attach-module], but the module
specified by @racket[modname] need only be declared (and not
necessarily @tech{instantiate}d) in @racket[src-namespace], and the
module is merely declared in @racket[dest-namespace].}
@defproc[(namespace-unprotect-module [inspector inspector?]
[modname module-path?]
[namespace namespace? (current-namespace)])
void?]{
Changes the inspector for the instance of the module referenced by
@racket[modname] in @racket[namespace]'s @tech{module registry} so
that it is controlled by the current code inspector. The given
@racket[inspector] must currently control the invocation of the module
in @racket[namespace]'s @tech{module registry}, otherwise the
@exnraise[exn:fail:contract]. See also @secref["modprotect"].}
@defproc[(namespace-module-registry [namespace namespace?])
any]{
Returns the @tech{module registry} of the given namespace. This value
is useful only for identification via @racket[eq?].}
@defproc[(module->namespace [mod (or/c module-path?
resolved-module-path?
module-path-index?)])
namespace?]{
Returns a namespace that corresponds to the body of an instantiated
module in the current namespace's @tech{module registry} and in the
current namespace's @tech{base phase}, making the module
@tech{available} for on-demand @tech{visits} at the namespace's
@tech{base phase}. The returned namespace has the same @tech{module
registry} as the current namespace. Modifying a binding in the
namespace changes the binding seen in modules that require the
namespace's module.
Module paths in a top-level @racket[require] expression are resolved
with respect to the namespace's module. New @racket[provide]
declarations are not allowed.
If the current code inspector does not control the invocation of the
module in the current namespace's @tech{module registry}, the
@exnraise[exn:fail:contract]; see also @secref["modprotect"].
Bindings in the namespace cannot be modified if the
@racket[compile-enforce-module-constants] parameter was true when the
module was declared, unless the module declaration itself included
assignments to the binding via @racket[set!].}
@defproc[(namespace-syntax-introduce [stx syntax?]) syntax?]{
Returns a syntax object like @racket[stx], except that the current
namespace's bindings are included in the @tech{syntax object}'s
@tech{lexical information} (see @secref["stxobj-model"]). The
additional context is overridden by any existing @tech{top-level
bindings} in the @tech{syntax object}'s @tech{lexical information}, or
by any existing or future @tech{module bindings} in the @tech{lexical
information}.}
@defproc[(module-provide-protected? [module-path-index (or/c symbol? module-path-index?)]
[sym symbol?])
boolean?]{
Returns @racket[#f] if the module declaration for
@racket[module-path-index] defines @racket[sym] and exports it
unprotected, @racket[#t] otherwise (which may mean that the symbol
corresponds to an unexported definition, a protected export, or an
identifier that is not defined at all within the module).
The @racket[module-path-index] argument can be a symbol; see
@secref["modpathidx"] for more information on module path
indices.
Typically, the arguments to @racket[module-provide-protected?]
correspond to the first two elements of a list produced by
@racket[identifier-binding].}
@defproc[(variable-reference? [v any/c]) boolean?]{
Return @racket[#t] if @racket[v] is a @tech{variable reference}
produced by @racket[#%variable-reference], @racket[#f] otherwise.}
@defproc[(variable-reference-constant? [varref variable-reference?]) boolean?]{
Returns @racket[#t] if the variable represented by @racket[varref]
will retain its current value (i.e., @racket[varref] refers to a
variable that cannot be further modified by @racket[set!] or
@racket[define]), @racket[#f] otherwise.}
@defproc[(variable-reference->empty-namespace [varref variable-reference?])
namespace?]{
Returns an empty namespace that shares module declarations and
instances with the namespace in which @racket[varref] is instantiated,
and with the same phase as @racket[varref].}
@defproc[(variable-reference->namespace [varref variable-reference?])
namespace?]{
If @racket[varref] refers to a @tech{module-level variable}, then the
result is a namespace for the module's body in the referenced
variable's @tech{phase}; the result is the same as a namespace
obtained via @racket[module->namespace].
If @racket[varref] refers to a @tech{top-level variable}, then the
result is the namespace in which the referenced variable is defined.}
@defproc[(variable-reference->resolved-module-path [varref variable-reference?])
(or/c resolved-module-path? #f)]{
If @racket[varref] refers to a @tech{module-level variable}, the
result is a @tech{resolved module path} naming the module.
If @racket[varref] refers to a @tech{top-level variable}, then the
result is @racket[#f].}
@defproc[(variable-reference->module-path-index [varref variable-reference?])
(or/c module-path-index? #f)]{
If @racket[varref] refers to a @tech{module-level variable}, the
result is a @tech{module path index} naming the module.
If @racket[varref] refers to a @tech{top-level variable}, then the
result is @racket[#f].}
@defproc[(variable-reference->module-source [varref variable-reference?])
(or/c symbol? (and/c path? complete-path?) #f)]{
If @racket[varref] refers to a @tech{module-level variable}, the
result is a path or symbol naming the module's source (which is
typically, but not always, the same as in the @tech{resolved module
path}). If the relevant module is a @tech{submodule}, the result
corresponds to the enclosing top-level module's source.
If @racket[varref] refers to a @tech{top-level variable}, then the
result is @racket[#f].}
@defproc[(variable-reference->phase [varref variable-reference?])
exact-nonnegative-integer?]{
Returns the @tech{phase} of the variable referenced by @racket[varref].}
@defproc[(variable-reference->module-base-phase [varref variable-reference?])
exact-integer?]{
Returns the @tech{phase} in which the module is instantiated for the
variable referenced by @racket[varref], or @racket[0] if the variable
for @racket[varref] is not within a module.
For a variable with a module, the result is less than the result of
@racket[(variable-reference->phase varref)] by @math{n} when the
variable is bound at @tech{phase level} @math{n} within the module.}
@defproc[(variable-reference->module-declaration-inspector [varref variable-reference?])
inspector?]{
Returns the declaration @tech{inspector} (see @secref["modprotect"])
for the module of @racket[varref], where @racket[varref] must refer to
an anonymous module variable as produced by
@racket[(#%variable-reference)].}