LISP - Quick Reference
Basic Overview
This is about LISP, a programming language that takes
its name from
List
Processing. LISP is a symbol-manipulation
language. A symbol-manipulation language is like working with words and
sentences. In LISP, we have the following basic data types:
-
S-EXPRESSIONS (or symbolic expressions or simply expressions)
= It can be an Atom, a List, or a collection of S-Expressions enclosed
by parentheses.
-
NIL is equivalent to the Empty List (i.e. () ), so NIL is
both an atom and a list.
-
ATOM = It is a string of characters beginning with a letter,
digit or special character other than left "(" or right ")"
parentheses. We divide in:
-
Numeric Atoms or numbers (e.g. 27, 3.14).
-
Symbolic Atoms or symbols. (e.g. FOO, B52, FIRST, + , PETER,
HYPHEN-SYMBOL).
-
LIST = Consists of a left parenthesis, followed by
zero or more atoms or list, followed by a right parenthesis.
-
E.g. (The letters A B C)
(3.1416 ((yesterday) today) tomorrow)
LISP's Terms:
|------- LIST--------|
|
Procedure is the
name of the thing to do, it is always specified and followed then by the
Argument(s),
the name of the thing(s) the procedure is to work with. Element(s)
are the generic name of the thing(s) we find enclosed by parentheses and separated by spaces. |
( +
1.23 3.45 )
|
|
|-| |----| |----| |
|
Procedure Arguments |
|
|-| |----| |----|
Elements |
A procedure supplied by LISP itself, is called primitive
and
a procedure supplied by you in terms of LISP primitives is called a user-defined
procedure. A procedure that returns a
value that signals true or false is called predicate. |
" ' " or quote - returns arguments literally
'(+ 2 3) => (+ 2 3)
but (+ 2 3) => 5
setq (or setf) - assigns values to symbols
(setq n 8)=> 8
(setq colors '(blue
red))=>(BLUE RED)
first - returns the first element of a list. The same
of CAR.
(first '(A B C)) @
(car
'(A B C))=> A
rest - returns a list containing all but the first
element of a list. The same of CDR.
(rest '(A B C)) @
(cdr
'(A B C))=> (B C)
CAR and CDR - they can be run together to form
composite primitives of the form CxxR, CxxxR and CxxxxR. (Each x denotes
either an A (CAR) or a D (CDR)).
(cadr '(A B C)) @
(car
(cdr '(A B C))) @ (first (rest '(A B C)))=>
B
second, third,.... tenth - analogous to first
(third '(A B C D))=>
C
cons - takes an expression and a list and returns
a new list - (cons <expression> <list>)
(cons 'A '(B C))=>(A
B C)
append - combines the elements of all lists supplied
-
(append
<list1><list2>..<listN>)
(append '(A) '(B C))=>(A
B C)
(append '(A) '(B)
'(C))=>(A B C)
For CONS and APPEND, if the second
argument is not a list, you will get an odd result that looks like a list
but has a dot before the last element.
list - it makes a list out of its arguments. Each
argument becomes an element of the new list -
(list<expression1><expression2>...<expressionN>).
(list 'A 'B 'C)=>(A
B C)
(list '(A) '(B) '(C))=>((A)
(B) (C))
(list 'A '(B C) (+
1 2))=>(A (B C) 3)
(list 'A '(B C) '(+ 1 2))=>(A (B C) (+ 1
2))
nth - nth entry of list (note that n
starts
at 0, not 1) - (nth n <list>)
(nth 2 '(A B C D))=>
C
nthcdr - trims off n elements - (nthcdr
<n>
<list>)
(nthcdr 2 '(A B C
D))=>(C D)
(nthcdr 5 '(A B C
D))=>NIL
butlast - trims off the last n elements
- (butlast
<list> <n>)
(butlast '(A B C D)
2)=>(A B)
(butlast '(A B C D))=>(A
B C)
last - returns a list of the last element of a list
- (last <list>)
(last '(A B C))=>(C)
length - counts the number of top-level elements
- (length <list>)
(length '(A B C))=>3
(length '((A A) (B
B) (C C))=>3
reverse - reverse the order of the top-level elements
of a list - (reverse <list>)
(reverse '(A B C))=>
(C B A)
(reverse '((A A) (B
B)(C C))=>((C C)(B B)(A A))
+, -, *, / - returns sum, difference, product, or
quotient
(+ 2 3 4)=> 9
(/ (+ 2 2) (- 3 1))=>
2
abs, round - Absolute value, nearest integer
(round (abs -5.3))=>
5
max, min - maximum or minimum of numbers
(max 1 2 5 4 3)=>
5
sqrt - square root of number
(sqrt 16)=> 4
expt - baseexponent - (expt <base>
<exponent>)
(expt 2 3)=> 8
defun - procedure-definition primitive -
(defun <function-name> ( <parameter1><parameter2>...<parameterN>)<body>)
(defun square(n) (*
n n))=>SQUARE
(square 4)=> 16
let - binds parameters to initial values. evaluates
initial-forms in parallel -
(let ((<parameter1><initial value1>)
(<parameter2><initial value2>)...<parameterN><initial valueN>))
<body> )
(setq x 'out)
(let ((x 'in)(y x))(list
x y)=>(IN OUT)
let* - binds parameters to initial values -
evaluates initial-forms sequentially -
(let*((<parameter1><initial value1>)(<parameter2><initial
value2>)...<parameterN><initial valueN>)) <body> )
(setq x 'out)
(let* ((x 'in)(y x))(list
x y)=>(IN IN)
null, endp - check if the argument is an empty
list. Note that the argument of endp must be a list -
(null 'a)=>NIL
(null ( ))=>T
(endp '(A B C ))=>NIL
(endp 'F)=>error
atom, numberp, listp, symbolp - predicates that
test if argument is a atom, number, list or symbol,
respectively -
(numberp pi)=>T
(listp 'pi )=>NIL
(symbolp pi)=>NIL
(symbolp 'pi)=>T
zerop, plusp, minusp, <, >, =, evenp, oddp -
Numeric
predicates - these will give errors for
non-numbers -
(zerop 3)=> NIL
( > 4 2)=>T
equal - primitive that tests two arguments to
see if their values are the same expression -
(equal (+ 2 2) 4)=>T
(equal '(A B) '(C
D))=>NIL
(equal '(A B) (cons
'A '(B)))=>T
eq - primitive that tests two arguments to see
if they are represented by the same chunck of memory -
(setq list1 '(A B))
(setq list2 '(A B))
(setq list3 list1)
(eq list1 list2)=>NIL
(eq list1 list3)=>T
and, or, not - Logical predicates -
(not (and (= 7 (+ 2 5))(evenp 8)))=> NIL
if - conditional operator - (if <test>
<then-form or non-Nil form><else-form or Nil-form>) -
You also have the operators when
and
unless, the first one is used whenever the else-form is NIL and
the second whenever the <then-form>
is NIL -
(if (= 3 (+
1 2)) 'yes 'no)=>YES
cond - multiple conditional operator -
(cond (<test1><consequent1-1>..)(<test2><consequent2-1>..)(<testN><consequentN-1>..))
(setq n 7)
(cond ((symbolp n)
"symbol") ((numberp n) "number") (t "what is this ?"))=>T
bye - quits LISP.
(bye)
Recursion
- is one of several general strategies for controlling how a computation
evolves. Recursion allows procedure to use itself in its own definition,
either
directly or through
an intermediary.
e.g.
(defun recursive-expt (m n)
(if (zerop n) 1 (* m (recursive-expt m (- n 1)))))
(defun count-elements-main (l)
(count-elements-aux l 0 ))
(defun count-elements-aux (l result)
(if (endp l) result (count-elements-aux (rest l)(+ 1 result))))
Optional Parameters eliminate
the need for many auxiliaries.
e.g.
(defun root (x &optional n)
(Note: all parameters listed after &OPTIONAL are optional parameters.
(if n (expt x (/ 1 n)) (sqrt x)))
When ROOT is used with just one argument, Nis bound to NIL.)
or
(defun root (x &optional (n
2))
(You can specify default values to your optional parameters by surrouding
the
(expt x (/ 1 n)))
optional parameter and the default-value with parenteheses.)
( For further information, see
in our textbook - page 84.)
(Advanced programmers use &REST,
&KEy
and
&AUX.
for further information, see page 87.)
Iteration - is another
one of several general strategies for controlling how a computation evolves.
dotimes - used when iterating a given number of
times -
(dotimes(<counter parameter><upper bound><result>)<body>)
dolist - used when iterating over the elements
in a list -
(dolist(<element parameter><list><result form>)<body>)
do - used when dotimes and dolist
are not flexible enough. do is more general than both.
(do ( (<parameter1><initialvalue1><updateform1>)
(<parameter2><initialvalue2><updateform2>)
...
(<parameterN><initialvalueN><updateformN>) )
(<termination test><intermediate form, if any><result form>)
<body>)
loop
- the forms in the body are evaluated over
and over, until a return form is founded. -
(loop <body>)