#
Chapter 8
Namespaces

MzScheme supports multiple namespaces for top-level variable bindings, syntax bindings, module imports, and module declarations.

A new namespace is created with the ``make-namespace`` procedure, which returns a first-class namespace value. A namespace is used by setting the ``current-namespace`` parameter value (see section 7.9.1.5), by providing the namespace to procedures such as ``eval`` and `eval-syntax`. The MzScheme versions of the R5RS procedures `scheme-report-environment` and `null-environment` produce namespaces.21

The current namespace is used by many procedures, including ``eval``, ``load``, ``compile``, and ``expand``.22 After an expression is ``eval``ed, the global variable references in the expression are permanently attached to a particular namespace, so the current namespace at the time that the code is executed is not used as the namespace for referencing global variables in the expression.

Example:

    (define x 'orig) ; define in the original namespace
    ;; The following let expression is compiled in the original
    ;; namespace, so direct references to x see 'orig.
    (let ([n (make-namespace)]) ; make new namespace
      (parameterize ([current-namespace n])
        (eval '(define x 'new)) ; evals in the new namespace
        (display x) ; displays 'orig
        (display (eval 'x)))) ; displays 'new

A namespace actually encapsulates three top-level environments: one for normal expressions, one for macro transformer expressions, and one for macro templates; see section 12 for more information about the transformer environment, and see section 12.3.4 for more information about the template environment. Module declarations are shared by the environments, but module instances, variable bindings, syntax bindings, and module imports are distinct. More precisely, the transformer environment never contains any syntax bindings, and its variables, module instances, and module imports are distinct from the variables, module instances, and module imports of the normal top-level environment. The template environment contains module imports, only.

Each namespace has a module registry that maps module names to module declarations (see Chapter 5). The `module->namespace` procedure returns a namespace with the same module registry as the current namespace, but whose environment and bindings correspond to the body of an instantiated module. (This facility is primarily useful for debugging, and its use is limited by the current code inspector; see also section 9.4.)

## 8.1 Identifier Resolution in Namespaces

Identifier resolution in a namespace's top-level environment, for compilation or expansion, proceeds in two steps. First, the environment determines whether the identifier is mapped to a top-level variable, to syntax, or to a module import (which can be either syntax or a variable). Second, if the identifier is mapped to a top-level variable, then the variable's location is found; if the identifier is mapped to syntax, then the expansion-time binding is found; and if the identifier is mapped to an import, then the source module is consulted.

Importing a variable from a module with `require` is not the same as defining the variable; the import does not create a new top-level variable in the environment, but instead maps an identifier to the module's variable, in the same way that a syntax definition maps an identifier to a transformer.

Redefining a previously-defined variable is the same as mutating the variable with `set!`. Rebinding a syntax-bound or import-bound identifier (to syntax or an import) replaces the old binding with the new one for future uses of the environment.

If an identifier is bound to syntax or to an import, then defining the identifier as a variable shadows the syntax or import in future uses of the environment. Similarly, if an identifier is bound to a top-level variable, then binding the identifier to syntax or an import shadows the variable; the variable's value remains unchanged, however, and may be accessible through previously evaluated expressions.

Example:

    (define x 5)
    (define (f) x)
    x ; => 5
    (f) ; => 5
    (define-syntax x (syntax-rules ()))
    x ; =>  bad syntax
    (f) ; => 5
    (define x 7)
    x ; => 7
    (f) ; => 7
    (module m mzscheme (define x 8) (provide x))
    (require m)
    x ; => 8
    (f) ; => 7

## 8.2 Initial Namespace

In the stand-alone MzScheme application, the initial namespace's module registry contains declarations for ``mzscheme`` and the primitive `#%`-named modules (see section 5.7). The normal top-level environment of the initial namespace contains imports for all MzScheme syntax, and it contains variable bindings (as opposed to imports) for every built-in procedure and constant. The transformer top-level environment of the initial namespace imports all MzScheme syntax, procedures, and constants.

Applications embedding MzScheme may extend or modify the set of initial bindings, but they will usually only add primitive modules with `#%`-prefixed names. (MrEd adds `#%mred-kernel` for its graphical toolbox.)

## 8.3 Namespace Utilities

`(make-namespace``` [`flag-symbol`]`)` creates a new namespace with a new module registry; the `flag-symbol` is an option that determines the initial bindings in the namespace. The allowed values for `flag-symbol` are:

- `'initial` (the default) -- the new namespace contains the module declarations of the initial namespace (see section 8.2), and the new namespace's normal top-level environment contains bindings and imports as in the initial namespace. However, the namespace's transformer top-level environment is empty.

- `'empty` -- creates a namespace with no initial bindings or module declarations.

`(namespace?``` `v``)` returns `#t` if `v` is a namespace value, `#f` otherwise.

`(namespace-symbol->identifier``` `symbol``)` is similar to `datum->syntax-object` (see section 12.2.2) restricted to symbols. The lexical context of the resulting identifier corresponds to the top-level environment of the current namespace; the identifier has no source location or properties.

`(namespace-variable-value``` `symbol``` [`use-mapping? failure-thunk namespace`]`)` returns a value for `symbol` in `namespace`, where `namespace` defaults to the current namespace. The returned value depends on `use-mapping?`:

- If `use-mapping?` is true (the default), and if `symbol` maps to a top-level variable or an imported variable (see section 8.1), then the result is the same as evaluating `symbol` as an expression. If `symbol` maps to syntax or imported syntax, the `exn:fail:syntax` exception is raised (or `failure-thunk` is called; see below). If `symbol` is mapped to an undefined variable or an uninitialized module variable, the `exn:fail:contract:variable` exception is raised (or `failure-thunk` is called).

- If `use-mapping?` is false, the namespace's syntax and import mappings are ignored. Instead, the value of the top-level variable named `symbol` in namespace is returned. If the variable is undefined, the `exn:fail:contract:variable` exception is raised (or `failure-thunk` is called).

If `failure-thunk` is provided, `namespace-variable-value` calls `failure-thunk` to produce the return value in place of raising an `exn:fail:contract:variable` or `exn:fail:syntax` exception.

`(namespace-set-variable-value!``` `symbol v``` [`map? namespace`]`)` sets the value of `symbol` in the top-level environment of `namespace` (where `namespace` defaults to the current namespace) defining `symbol` if it is not already defined. If `map?` is supplied as true, then the namespace's identifier mapping is also adjusted (see section 8.1) so that `symbol` maps to the variable. The default value for `map?` is `#f`.

`(namespace-undefine-variable!``` `symbol namespace``)` removes the `symbol` variable, if any, in the top-level environment of the `namespace`, where `namespace` defaults to the current namespace. The namespace's identifier mapping is unaffected.

`(namespace-mapped-symbols``` [`namespace`]`)` returns a list of all symbols that are mapped to variables, syntax, and imports in `namespace`, where `namespace` defaults to the current namespace.

`(namespace-require``` `quoted-require-spec``)` performs the import corresponding to `quoted-require-spec` in the top-level environment of the current namespace (like a top-level `require` expression). See also Chapter 5. Module paths in `quoted-require-spec` are not resolved with respect to any other module, even if the current namespace corresponds to a module body.

`(namespace-transformer-require``` `quoted-require-spec``)` performs the import corresponding to `quoted-require-spec` in the top-level transformer environment (like a top-level `require-for-syntax` expression). See also Chapter 5. Module paths in `quoted-require-spec` are not resolved with respect to any other module, even if the current namespace corresponds to a module body.

`(namespace-require/copy``` `quoted-require-spec``)` is like `namespace-require` for syntax exported from the module, but exported variables are treated differently: the export's current value is copied to a top-level variable in the current namespace.

`(namespace-require/expansion-time``` `quoted-require-spec``)` is like `namespace-require`, but only the transformer part of the module is executed. If the required module has not been invoked before, the module's variables remain undefined.

`(namespace-attach-module``` `src-namespace module-path-v``` [`dest-namespace`]`)` attaches the instantiated module named by `module-path-v` in `src-namespace` to the registry of `dest-namespace` (which is the current namespace if `dest-namespace` is not supplied). If `module-path-v` is not a symbol, the current module name resolver is called to resolve the path, but no module is loaded; the resolved form of `module-path-v` is used as the module name in `dest-namespace`. In addition to `module-path-v`, every module that it imports (directly or indirectly) is also recorded in the current namespace's registry. If `module-path-v` does not refer to an instantiated module in `src-namespace`, or if the name of any module to be attached already has a different declaration or instance in `dest-namespace`, then the `exn:fail:contract` exception is raised. The inspector of the module invocation in `dest-namespace` is the same as inspector of the invocation in `src-namespace`.

`(namespace-unprotect-module``` `inspector module-path-v``)`namespace changes the inspector for the instance of the module referenced by `module-path-v` in `namespace`'s registry so that it is controlled by the current code inspector. If `namespace` is not supplied, it is the current namespace. The given `inspector` must currently control the invocation of the module in `namespace`'s registry, otherwise the `exn:fail:contract` exception is raised. See also section 9.4.

`(namespace-module-registry``` `namespace``)` returns the registry of the given namespace. This value is useful only for identification via ``eq?``.

`(module->namespace``` `module-path-v``)` returns a namespace that corresponds to the body of an instantiated module in the current namespace's registry. The returned namespace has the same 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 `require` expression are resolved with respect to the namespace's module. New `provide` declarations are not allowed. If the current code inspector does not control the invocation of the module in the current namespace's registry, the `exn:fail:contract` exception is raised; see also section 9.4. Bindings in the namespace cannot be modified if the `compile-enforce-module-constants` parameter was true when the module was declared, unless the module declaration itself included assignments to the binding via `set!`.

`(namespace-syntax-introduce``` `stx``)` returns a syntax object like `stx`, except that the current namespace's bindings are included in the syntax object's context (see section 12.3). The additional context is overridden by any existing top-level context in the syntax object, or by any existing or future module context. See section 12.2 for more information about syntax objects.

`(module-provide-protected?``` `module-path-index symbol``)` returns `#f` if the module declaration for `module-path-index` defines `symbol` and exports it unprotected, `#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 `module-path-index` argument can be a symbol; see section 12.6.5 for more information on module path indices. Typically, the arguments to ``module-provide-protected?`` correspond to the first two elements of a list produced by ``identifier-binding`` (see section 12.3).

21 The resulting namespace contains syntax imports for `#%app`, `#%datum`, and `#%top`, because syntax expansion requires them (see section 12.5), but those names are not legal R5RS identifiers.

22 More precisely, the current namespace is used by the evaluation and load handlers, rather than directly by ``eval`` and ``load``.