### 13.1 Environment Operations

Environments are first-class objects in MIT/GNU 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