Chapter 2Basic concepts

1Variables, 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.