Chapter 2. Basic concepts
1. Variables, keywords, and regions
Scheme is a statically scoped language with block structure.
To each place in a top-level program or library body where an
identifier is bound there corresponds a region of code within
which the binding is visible. The region is determined by the
particular binding construct that establishes the binding; if
the binding is established by a lambda expression,
for example, then its region consists of the formals and body
of that lambda expression. Every mention of an
identifier refers to the binding of the identifier that
establishes the innermost of the regions containing the use.
If a use of an identifier appears in a place where none of
the surrounding expressions contains a binding for the
identifier, the use may refer to a binding established by a
definition or import at the top of the enclosing library or
top-level program. If there is no binding for the identifier,
it is said to be unbound.
Within the body of a library or top-level program, an identifier may name a kind of syntax, or it may name a location where a value can be stored. An identifier that names a kind of syntax is called a keyword, or syntax keyword, and is said to be bound to that kind of syntax (or, in the case of a syntactic abstraction, a transformer that translates the syntax into more primitive forms; see ). An identifier that names a location is called a variable and is said to be bound to that location. At each point within a top-level program or a library, a specific, fixed set of identifiers is bound. The set of these identifiers, the set of visible bindings, is known as the environment in effect at that point. The value stored in the location to which a variable is bound is called the variable’s value. By abuse of terminology, the variable is sometimes said to name the value or to be bound to the value. This is not quite accurate, but confusion rarely results from this practice.
A variable’s value can be accessed, which occurs when
an expression which consists only of the variable’s name is evaluated
(see the section called “Variables”); and a variable’s value can
be assigned, which occurs when a set! expression affecting
the variable is evaluated (see ???). A variable can also be referred to, which occurs when an expression
which would, if evaluated, access or assign the value of that variable
appears in code in that variable’s region, without necessarily evaluating
that code. In some contexts, this report restricts the ability to refer
to, access the value of, or assign the value of some variables. For
example, it is not permitted for code within a library to attempt to assign the value of a variable which it has
imported from another library, but that variable can be freely referred
to and its value accessed in any context in that library. Likewise, in
the context of a letrec or letrec* expression (see ???), there is no restriction on referring to variables’ names, but an
attempt to evaluate an expression which accesses or assigns the value
of a variable bound by those expressions can cause an error to be
signalled, if its value has not yet been determined according to the
evaluation rules of those expressions. Finally, in the context of a
body (see Section 2.6, “Bodies”), it can cause an error to
be signalled if a variable is only referred to, if that variable’s
definition occurs in a group of definitions which appears to the right
of the expression which refers to it.
Certain expression types are used to create syntactic
abstractions and to bind keywords to transformers for those new syntactic
abstractions, while other forms create new locations and bind variables
to those locations. Collectively, these forms are called binding
constructs. Some binding constructs take the form of definitions, while
others are expressions. With the exception of exported library bindings,
a binding created by a definition is visible only within the body in
which the definition appears, e.g., the body of a library, top-level
program, or lambda expression. Exported library bindings
are also visible within the bodies of the libraries and top-level programs
that import them.