Next: , Previous: Macro Primitives, Up: Syntax


4.9.5 Environment Frames

An environment is a list of frames representing lexical bindings. Only the names and scope of the bindings are included in environments passed to macro expanders – run-time values are not included.

There are several types of environment frames:

((lambda (variable1 ...) ...) value1 ...)
(let ((variable1 value1) (variable2 value2) ...) ...)
(letrec ((variable1 value1) ...) ...)
result in a single enviroment frame:
          
          (variable1 variable2 ...)
          

(let ((variable1 value1)) ...)
(let* ((variable1 value1) ...) ...)
result in an environment frame for each variable:
          
          variable1 variable2 ...
          

(let-syntax ((key1 macro1) (key2 macro2)) ...)
(letrec-syntax ((key1 value1) (key2 value2)) ...)
Lexically bound macros result in environment frames consisting of a marker and an alist of keywords and macro objects:
          
          (<env-syntax-marker> (key1 . value1) (key2 . value2))
          

Currently <env-syntax-marker> is the integer 6.

line numbers
Line numbers (see Line Numbers) may be included in the environment as frame entries to indicate the line number on which a function is defined. They are ignored for variable lookup.
          
          #<line 8>
          

miscellaneous
Debugging information is stored in environments in a plist format: Any exact integer stored as an environment frame may be followed by any value. The two frame entries are ignored when doing variable lookup. Load file names, procedure names, and closure documentation strings are stored in this format.
          
          <env-filename-marker> "foo.scm" <env-procedure-name-marker> foo ...
          

Currently <env-filename-marker> is the integer 1 and <env-procedure-name-marker> the integer 2.

— Special Form: @apply procedure argument-list

Returns the result of applying procedure to argument-list. @apply differs from apply when the identifiers bound by the closure being applied are set!; setting affects argument-list.

          (define lst (list 'a 'b 'c))
          (@apply (lambda (v1 v2 v3) (set! v1 (cons v2 v3))) lst)
          lst           ⇒ ((b . c) b c)

Thus a mutable environment can be treated as both a list and local bindings.