This is the first thing you need to know about Lisp: anything surrounded by parentheses is a list. Here are some examples of things that are lists:
(1 2 3 4 5) (a b c) (cat 77 dog 89)
As I said, anything surrounded by parentheses is a list. When you hear a statement like that, you probably want to ask two questions:
In both cases the answer is the same. You still have a list. So the following are also lists:
() (()) ((())) ((a b c)) ((1 2) 3 4) (mouse (monitor 512 342) (keyboard US)) (defun factorial (x) (if (eql x 0) 1 (* x (factorial (- x 1)))))
The only time you don't have a list is when you have a right parenthesis without a matching left parenthesis or vice versa, as in the following four examples:
(a b c( ((25 g) 34 ((()) (()))
This is nothing to lose sleep over -- Lisp will tell you when there's a mismatch. Also, the editor that you use for writing Lisp programs will almost certainly give you a way to automatically find matching parentheses. We'll look at editors in Chapter 27.
A list can be a lot of things in Lisp. In the most general sense, a list can be either a program or data. And because lists can themselves be made of other lists, you can have arbitrary combinations of data and programs mixed at different levels of list structure -- this is what makes Lisp so flexible for those who understand it, and so confusing for those who don't. We'll work hard to remove that confusion as this chapter continues.
Accordingly, these words and numbers are all atoms:
1 25 342 mouse factorial x
Lisp lets us use just about any characters to make up an atom. For now, we'll say that any sequence of letters, digits, and punctuation characters is an atom if it is preceded and followed by a blank space (this includes the beginning or end of a line) or a parenthesis. The following are all atoms:
- * @comport funny%stuff 9^ case-2
One thing you should remember, if you're experienced in another
programming language, is that characters traditionally reserved as
operators have no special meaning when they appear within a Lisp atom. For
example, case-2
is an atom, and not an arithmetic
expression.
Since an atom can be marked off by either whitespace or a parenthesis, we could eliminate any whitespace between an atom and a parenthesis, or between two parentheses. Thus, the following two lists are identical:
(defun factorial (x) (if (eql x 0) 1 (* x (factorial (- x 1))))) (defun factorial(x)(if(eql x 0)1(* x(factorial(- x 1)))))
In practice, we'd never write the second list. In fact, we'd probably split the list across multiple lines and indent each line to improve readability; this list is in fact a small program, and formatting it as follows makes it easier to read for a Lisp programmer:
(defun factorial (x) (if (eql x 0) 1 (* x (factorial (- x 1)))))
For now, you don't need to worry about what this means or how you'd know to do this kind of indentation. As we get further into this chapter, you'll see more examples of indentation. Subsequent chapters will show additional examples, and I'll point out how to use indentation to improve readability of many new constructs. Chapter 28 will address elements of Lisp style, including the proper use of indentation.