[ < ] | [ > ] |  | [ << ] | [ Up ] | [ >> ] |  |  |  |  | [Top] | [Contents] | [Index] | [ ? ]

# 13. Environments

> 13.1 Environment Operations |  |
> 13.2 Environment Variables |  |
> 13.3 REPL Environment |  |
> 13.4 Top-level Environments |  |

[ < ] | [ > ] |  | [ << ] | [ Up ] | [ >> ] |  |  |  |  | [Top] | [Contents] | [Index] | [ ? ]

## 13.1 Environment Operations

Environments are first-class objects in MIT Scheme. An environment consists of some bindings and possibly a parent environment, from which other bindings are inherited. The operations in this section reveal the frame-like structure of environments by permitting you to examine the bindings of a particular environment separately from those of its parent.

There are several types of bindings that can occur in an environment. The most common is the simple variable binding, which associates a value (any Scheme object) with an identifier (a symbol). A variable binding can also be unassigned, which means that it has no value. An unassigned variable is bound, in that is will shadow other bindings of the same name in ancestor environments, but a reference to that variable will signal an error of type `condition-type:unassigned-variable`. An unassigned variable can be assigned (using `set!` or `environment-assign!`) to give it a value.

In addition to variable bindings, an environment can also have keyword bindings. A keyword binding associates a syntactic keyword (usually a macro transformer) with an identifier. Keyword bindings are special in that they are considered "bound", but ordinary variable references don't work on them. So an attempt to reference or assign a keyword binding results in an error of type `condition-type:macro-binding`. However, keyword bindings can be redefined using `define` or `environment-define`.

procedure: environment? object
  Returns `#t` if object is an environment; otherwise returns `#f`.

procedure: environment-has-parent? environment
  Returns `#t` if environment has a parent environment; otherwise returns `#f`.

procedure: environment-parent environment
  Returns the parent environment of environment. It is an error if environment has no parent.

procedure: environment-bound-names environment
  Returns a newly allocated list of the names (symbols) that are bound by environment. This does not include the names that are bound by the parent environment of environment. It does include names that are unassigned or keywords in environment.

procedure: environment-macro-names environment
  Returns a newly allocated list of the names (symbols) that are bound to syntactic keywords in environment.

procedure: environment-bindings environment
  Returns a newly allocated list of the bindings of environment; does not include the bindings of the parent environment. Each element of this list takes one of two forms: `(symbol)` indicates that symbol is bound but unassigned, while `(symbol object)` indicates that symbol is bound, and its value is object.

procedure: environment-reference-type environment symbol
  Returns a symbol describing the reference type of symbol in environment or one of its ancestor environments. The result is one of the following:

  `normal`
    means symbol is a variable binding with a normal value.

  `unassigned`
    means symbol is a variable binding with no value.

  `macro`
    means symbol is a keyword binding.

  `unbound`
    means symbol has no associated binding.

procedure: environment-bound? environment symbol
  Returns `#t` if symbol is bound in environment or one of its ancestor environments; otherwise returns `#f`. This is equivalent to

      (not (eq? 'unbound
                (environment-reference-type environment symbol)))

procedure: environment-assigned? environment symbol
  Returns `#t` if symbol is bound in environment or one of its ancestor environments, and has a normal value. Returns `#f` if it is bound but unassigned. Signals an error if it is unbound or is bound to a keyword.

procedure: environment-lookup environment symbol
  Symbol must be bound to a normal value in environment or one of its ancestor environments. Returns the value to which it is bound. Signals an error if unbound, unassigned, or a keyword.

procedure: environment-lookup-macro environment symbol
  If symbol is a keyword binding in environment or one of its ancestor environments, returns the value of the binding. Otherwise, returns `#f`. Does not signal any errors other than argument-type errors.

procedure: environment-assignable? environment symbol
  Symbol must be bound in environment or one of its ancestor environments. Returns `#t` if the binding may be modified by side effect.

procedure: environment-assign! environment symbol object
  Symbol must be bound in environment or one of its ancestor environments, and must be assignable. Modifies the binding to have object as its value, and returns an unspecified result.

procedure: environment-definable? environment symbol
  Returns `#t` if symbol is definable in environment, and `#f` otherwise. At present, this is false for environments generated by application of compiled procedures, and true for all other environments.

procedure: environment-define environment symbol object
  Defines symbol to be bound to object in environment, and returns an unspecified value. Signals an error if symbol isn't definable in environment.

procedure: environment-define-macro environment symbol transformer
  Defines symbol to be a keyword bound to transformer in environment, and returns an unspecified value. Signals an error if symbol isn't definable in environment. The type of transformer is defined by the syntax engine and is not checked by this procedure. If the type is incorrect this will subsequently signal an error during syntax expansion.

procedure: eval expression environment
  Evaluates expression, a list-structure representation (sometimes called s-expression representation) of a Scheme expression, in environment. You rarely need `eval` in ordinary programs; it is useful mostly for evaluating expressions that have been created "on the fly" by a program. `eval` is relatively expensive because it must convert expression to an internal form before it is executed.

      (define foo (list '+ 1 2))
      (eval foo (the-environment))            =>  3

[ < ] | [ > ] |  | [ << ] | [ Up ] | [ >> ] |  |  |  |  | [Top] | [Contents] | [Index] | [ ? ]

## 13.2 Environment Variables

The `user-initial-environment` is where the top-level read-eval-print (REP) loop evaluates expressions and binds definitions. It is a child of `system-global-environment`, which is where all of the Scheme system definitions are bound. All of the bindings in `system-global-environment` are available when the current environment is `user-initial-environment`. However, any new bindings that you create in the REP loop (with `define` forms or by loading files containing `define` forms) occur in `user-initial-environment`.

variable: system-global-environment
  The variable `system-global-environment` is bound to the distinguished environment that's the ancestor of most other environments (except for those created by `make-root-top-level-environment`). It is the parent environment of `user-initial-environment`. Primitives, system procedures, and most syntactic keywords are bound (and sometimes closed) in this environment.

variable: user-initial-environment
  The variable `user-initial-environment` is bound to the default environment in which typed expressions are evaluated by the top-level REP loop.

  Although all bindings in `system-global-environment` are visible to the REP loop, definitions that are typed at, or loaded by, the REP loop occur in the `user-initial-environment`. This is partly a safety measure: if you enter a definition that happens to have the same name as a critical system procedure, your definition will be visible only to the procedures you define in the `user-initial-environment`; the MIT Scheme system procedures, which are defined in `system-global-environment`, will continue to see the original definition.

[ < ] | [ > ] |  | [ << ] | [ Up ] | [ >> ] |  |  |  |  | [Top] | [Contents] | [Index] | [ ? ]

## 13.3 REPL Environment

procedure: nearest-repl/environment
  Returns the current REP loop environment (i.e. the current environment of the closest enclosing REP loop). When Scheme first starts up, this is the same as `user-initial-environment`.

procedure: ge environment
  Changes the current REP loop environment to environment. Environment can be either an environment or a procedure object. If it's a procedure, the environment in which that procedure was closed is the new environment.

[ < ] | [ > ] |  | [ << ] | [ Up ] | [ >> ] |  |  |  |  | [Top] | [Contents] | [Index] | [ ? ]

## 13.4 Top-level Environments

The operations in this section manipulate top-level environments, as opposed to environments created by the application of procedures. For historical reasons, top-level environments are referred to as interpreter environments.

special form: the-environment
  Returns the current environment. This form may only be evaluated in a top-level environment. An error is signalled if it appears elsewhere.

procedure: top-level-environment? object
procedure: interpreter-environment? object
  Returns `#t` if object is an top-level environment; otherwise returns `#f`.

  `interpreter-environment?` is an alias for `top-level-environment?`.

procedure: extend-top-level-environment environment [names [values]]
procedure: make-root-top-level-environment [names [values]]
  Returns a newly allocated top-level environment. `extend-top-level-environment` creates an environment that has parent environment, while `make-root-top-level-environment` creates an environment that has no parent.

  The optional arguments names and values are used to specify initial bindings in the new environment. If specified, names must be a list of symbols, and values must be a list of objects. If only names is specified, each name in names will be bound in the environment, but unassigned. If names and values are both specified, they must be the same length, and each name in names will be bound to the corresponding value in values. If neither names nor values is specified, the environment will have no initial bindings.

procedure: link-variables environment1 symbol1 environment2 symbol2
  Defines symbol1 in environment1 to have the same binding as symbol2 in environment2, and returns an unspecified value. Prior to the call, symbol2 must be bound in environment2, but the type of binding is irrelevant; it may be a normal binding, an unassigned binding, or a keyword binding. Signals an error if symbol1 isn't definable in environment1, or if symbol2 is unbound in environment2.

  By "the same binding", we mean that the value cell is shared between the two environments. If a value is assigned to symbol1 in environment1, a subsequent reference to symbol2 in environment2 will see that value, and vice versa.

procedure: unbind-variable environment symbol
  If symbol is bound in environment or one of its ancestor environments, removes the binding, so that subsequent accesses to that symbol behave as if the binding never existed. Returns `#t` if there was a binding prior to the call, and `#f` if there wasn't.

[ << ] | [ >> ] |  |  |  |  |  | [Top] | [Contents] | [Index] | [ ? ]

This document was generated by Chris Hanson on June, 17 2002 using texi2html