#
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.7.1.5), or providing the namespace as the second argument to ``eval``. The MzScheme versions of the R5RS procedures `scheme-report-environment` and `null-environment` produce namespaces.12

The current namespace is used by ``eval``, ``load``, ``compile``, ``expand``, and ``expand-once``.13 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 two top-level environments: one for normal expressions, and one for macro transformer expressions; see section 12 for more information about the transformer 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 variable or syntax bindings, and its module instances and imports are distinct from the instances and imports of the normal top-level environment.

## 8.1 Identifier Resolution in Namespaces

Identifier resolution in the 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 contains module 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; 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`]`)` returns a value for `symbol` in 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: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: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: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:variable` or `exn:syntax` exception.

`(namespace-set-variable-value!``` `symbol v``` [`map?`]`)` sets the value of `symbol` in the top-level environment of 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-mapped-symbols``)` returns a list of all symbols that are mapped to variables, syntax, and imports in the current namespace.

`(namespace-require``` `quoted-require-spec``)` performs the import corresponding to `quoted-require-spec` in the top-level environment (like a top-level `require` expression). See also Chapter 5.

`(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.

`(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-symbol``)` attaches the instantiated module named `module-symbol` in `src-namespace` to the current namespace, using `module-symbol` as the module name in the current namespace. In addition to the `module-symbol` module itself, every module that it imports (directly or indirectly) is also transferred into the current namespace. If `module-symbol` is not the name of an instantiated module in `src-namespace`, or if the name of any module to be transferred already has a different declaration or instance in the current namespace, then the `exn:application:mismatch` exception is raised.

12 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.

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