next up previous
Next: 2.2 Constants Up: 2. THE LISP INTERPRETER Previous: 2. THE LISP INTERPRETER

2.1 Variables

A variable is a symbol that is used to represent an argument of a function. Thus one might write "a + b, where a = 341 and b = 216". In this situation no confusion can result and all will agree that the answer is 557. In order to arrive at this result, it is neccessary to substitute the actual numbers for the variables, and then add the two number (on an adding machine for instance).

One reason why there is no ambiguity in this case is that "a" and "b" are not aceptable inputs for an adding machine, and it is therefore obvious that they merely represent the actual arguments. In LISP, the situation can be much more complicated. An atomic symbol may be either a variable or an actual argument. To further complicate the situation, a part of an argument may be a variable when a function inside another funct is evaluated. The intuitive approach is no longer adequate. An understanding of the formalism in use is necessary to do any effective LISP programming.

Lest the prospective LISP user be discouraged at this point, it should be pointed out that nothing new is going to be introduced here. This section is intended to reinforce the discussion of Section I. Everything in this section can be derived from the rule for translating M-expressions into S-expressions, or alternatively everything in this section can be inferred from the universal function evalquote of Section I.

The formalism for variables in LISP is the Church lambda notation. The part of the interpreter that binds variables is called apply. When apply encounters a function beginning with LAMBDA, the list of variables is paired with the list of arguments and added to the front of the a-list During the evaluation of the function, variables may be encountered. They are evaluated by looking them up on the a-list. If a variable has been bound several times, the last or most recent value is used. The part of the interpreter that does this is called eval. The following example will illustrate this discussion. Suppose the interpreter is given the following doublet:

fn:    (LAMBDA (X Y) (CONS X Y)) 
args: (A B)

evalquote will give these arguments to apply. (Look at the universal function of Section I.)

apply[(LAMBDA (X Y) (CONS X Y)); (A B);NIL]

apply will bind the variables and give the function and a-list to eval.

eval[(CONS X Y); ((X . A) (Y B))]

eval will evaluate the variables and give it to cons.

cons[A;B] = (A . B)

The actual interpreter skips one step required by the universal function, namely, apply[CONS;(A B);((X . A) (Y . B))].


next up previous
Next: 2.2 Constants Up: 2. THE LISP INTERPRETER Previous: 2. THE LISP INTERPRETER