A critical aspect of a programming language is the means it provides for using names to refer to computational objects. We say that the name identifies a variable whose value is the object.
In the Scheme dialect of Lisp, we name things with define. Typing
(define size 2)
causes the interpreter to associate the value 2 with the name size. 8 Once the name size has been associated with the number 2, we can refer to the value 2 by name:
( 5 size)
Here are further examples of the use of define:
(define pi 3.14159)
(define radius 10)
( pi ( radius radius))
(define circumference ( 2 pi radius))
Define is our language's simplest means of abstraction, for it allows us to use simple names to refer to the results of compound operations, such as the circumference computed above. In general, computational objects may have very complex structures, and it would be extremely inconvenient to have to remember and repeat their details each time we want to use them. Indeed, complex programs are constructed by building, step by step, computational objects of increasing complexity. The interpreter makes this step-by-step program construction particularly convenient because name-object associations can be created incrementally in successive interactions. This feature encourages the incremental development of programs is largely responsible for the fact that a Lisp program usually consists of a large number of relatively simple procedures.
It should be clear that the possibility of associating values with symbols and later retrieving them means that the interpreter must maintain some sort of memory that keeps track of the name-object pairs. This memory is called the environment (more precisely the global environment, since we will see later that a computation may involve a number of different environments). 9