To encode a conditional expression if p then x else y
we write:
(IF p x y)
Expressions are made into procedures (functions) by the use of Church’s lambda-notation. For example,
(LAMBDA (X Y) (+ (* 3 Y) X))
evaluates to a function of two arguments X
and Y
which computes . The list of variables names after the LAMBDA
indicates how the variables names in the expression are to be matched positionally to supplied arguments when the function is applied.
We can also encode recursive LISP programs as list data. For example, to compute N
factorial ():
(DEFINE FACTORIAL
(LAMBDA (N)
(IF (= N 0) 1
(* N (FACTORIAL (- N 1))))))
Suppose that we now want to write a LISP program which will take such a data structure and perform some useful operation on it, such as determining the value of an algebraic expression represented as a list structure. We need same procedures for categorizing, decomposing, and constructing LISP data.
The predicate ATOM
, when applied to a LISP datum, produces true when given an atom and false otherwise. The empty list (
) is considered to be an atom. The predicate ()
NULL
is true of only the empty list; its argument need not he a list, but may be any LISP datum. The predicate NUMBERP
is true of numbers and false of symbols and lists. The predicate EQ
, when applied to two symbols, is true if the two atomic symbols are identical. It is false when applied to two distinct symbols, or to a symbol and any other datum.
The decomposition operators for lists are traditionally called CAR
and CDR
for historical reasons. CAR
extracts the first element or a list, while CDR
produces a list containing all elements but the first. Because compositions of CAR
and CDR
are commonly used in LISP, an abbreviation is provided: all the C
’s and R
’s in the middle can be squeezed out. For example,
can be written as (CDR (CDR (CAR (CDR X))))
.
(CDDADR X)
The construction operator CONS
, given any datum and a list, produces a new list whose car is the datum and whose cdr is the given list; that is, CONS
adds a new element to the front of a list. The operator LIST
can take any number of arguments (a special feature), and produces a list of its arguments.
Notice that CONS
(and LIST
) conceptually create new data structures. As far as the LISP programmer is concerned, new data objects are available in endless supply. They can be conveniently called forth to serve some immediate purpose and discarded when they are no longer of use. While creation is