VI. The logic of functions

Any but the most trivial functions should begin with COND. The rest of the function consists of enumerating all the possible cases.

The first case should do the simplest work, in a nonrecursive fashion. For example, 90% of all functions that process a list will first test NULL, and deal directly with the empty list.

For each case after the first, you should notice what the above (failed) conditions are telling you. For example, if your first condition was (NULL L), then in the second clause you know that L is not the empty list (or you would never have gotten to the second clause).

Programming in LISP is largely a matter of enumerating all the possible cases and writing a clause to deal with each. In each clause you know that the tests of all the preceding clauses failed, and you write a test to bite off a small section of the possibilities that are left.

Be sure that you always check the arguments of a function for legality before you call the function with them. For example, don't call (CAR L) until you know that L is a nonempty list. Don't call (EQ X Y) until you know that X and Y are atoms.

Where algorithmic languages use assignment statements, sequential execution of statements, and loops, LISP uses function composition and recursion. Programmers used to an algorithmic language may therefore find LISP to be difficult and confusing. It takes some experience with the language before the beauty of LISP begins to be apparent.

Most implementations of LISP provide constructs similar to those found in algorithmic languages. These are best avoided by the beginning LISP programmer, as they allow the novice to ``write Fortran programs in LISP'' and never fully master the LISP approach to programming.

Previous page First page Next page

Copyright © 1995 by David Matuszek
All rights reserved.
Last updated July 15, 1995