Introduction

• LISP is one of the oldest computer programming
languages
• Invented by John McCarthy during late 1950s, shortly
after the development of FORTRAN.
• LISP (for LISt Processing) is particularly suited for AI
programs.
• It’s a language with a simple syntax, with little or no data
typing and dynamic memory management.




Introduction
• There are several variations of LISP including
FRANZLISP, INTERLISP, MACLISP, QLISP, SCHEME,
and COMMON LISP.
• The COMMON LISP version is the most recent, more
portable and easier to maintain. portable and easier to maintain.
• Like most traditional programming languages, LISP is
procedural i.e. LISP programs describe HOW to perform
an algorithm.




Introduction
• LISP is a FUNCTIONAL language. Its syntax and
semantics are derived from the mathematical theory of
recursive functions. Everything in LISP is a function.
• A function is a procedure that takes in one or more input
arguments and returns only one value, with no side
effect.
g(a, b) = a + b
• LISP is NOT a 'pure' functional language -
some of its functions produce side effects, e.g. SETF




The bowls analogy
• To understand LISTS and ATOMS.
• The easiest way to understand lists and atoms is to do
analogy with bowls, like those used to store things in a
refrigerator.
• Often refrigerator bowls are made to fit inside one • Often refrigerator bowls are made to fit inside one
another so that they are easy to store.
( )
( ) ( )
( ) ( ) ( )
+-----------------+ +-------+ +---+




The bowls analogy
We can put the small bowl inside the medium one:
( ( ) )
( +---+ )
+-------+
Then we can put the combination of the small and medium
bowls inside the big bowl:
( ( ( ) ) ) ( ( ( ) ) )
( ( +---+ ) )
( +-------+ )
+-----------------+
Here we can say that the small bowl is empty, the medium
bowl contains the small bowl, and the big bowl contains the
medium bowl.




The bowls analogy
Alternatively, we can put both the small bowl and the
medium bowl inside the big bowl this way:
( ( ) )
( ( ) ( ) )
( +-------+ +---+ )
+-----------------+
Here we say that both the small bowl and the medium bowl Here we say that both the small bowl and the medium bowl
are empty and that the big bowl contains both the small bowl
and the medium bowl.




The bowls analogy
We can also put some fruit in the bowls, represented here by
As for the Apples and a P for the Pear:
( ( ) )
( ( A A P ) ( ) )
( +-------+ +---+ )
+-----------------+
The small bowl is still empty; the medium bowl now contains
two apples and one pear; and the big bowl still contains the
small and medium bowls.




The bowls analogy
( ( ) )
( ) ( ( ) )
( A A P ) ( +-------+ P ) ( P )
+-------+ +-----------------+ +---+
Now there are two medium bowls: one contains two apples Now there are two medium bowls: one contains two apples
and one pear, and the other is empty. The large bowl contains
both a medium bowl and another pear. The small bowl
contains a pear, too.




LISTS and ATOMS
• The basic data objects in LISP are LISTS and ATOMS.
• LISTS are like BOWLS.
• Like bowls, lists can be empty.
• Like bowls, lists can contain other lists.
• Like bowls, lists can contain things that are not • Like bowls, lists can contain things that are not
containers.
• ATOMS are like the things people store in bowls.




LISTS and ATOMS
One bowl inside another inside another:
( ( ( ) ) )
( ( +---+ ) )
( +-------+ )
+-----------------+
One list inside another inside another:
( ( ( ) ) )
Here we can say that the inside list is empty; the empty list is
inside another list; the combination is, in turn, inside still
another list.




LISTS and ATOMS
( ( ) )
( ( A A P ) ( ) )
( +-------+ +---+ )
+-----------------+
List is:
( ( AA P ) ( ) )
One list is empty, just as one bowl was. Another list contains
three things, called atoms, just as one bowl contains three
pieces of fruit. There is a list containing two lists, just as there
is a bowl containing two bowls.




Basic Data Types of LISP
• Every expression in LISP is either an atom or a list.
• Indivisible things like 27, +, FIRST, FOO, which have
obvious meanings are called ATOMS.
• Atoms like 27, 3.14, etc. are called NUMERIC ATOMS.
• Atoms like FIRST, FOO, +, etc. are called SYMBOLIC
ATOMS.




Basic Data Types of LISP
• A list consists of a left parenthesis, followed by zero or
more elements, followed by a right parenthesis:
( a b c (d e) )
• Elements of a list are separated by space.
• Elements of a list are atoms or lists. • Elements of a list are atoms or lists.
• Both atoms and lists are called SYMBOLIC
EXPRESSIONS or s-expression.




++-- -- number number
| |
++-- -- atom + atom +
| | | |
Expression + + Expression + +-- -- symbol symbol Expression + + Expression + +-- -- symbol symbol
| |
++-- -- list list




Exercises
1. ATOM atom
2. (THIS IS AN ATOM) list
3. ((A B) (C D)) 3 (3) neither
4. (LIST 3) list
5. (/ (+ 3 1) (- 3 1)) list 5. (/ (+ 3 1) (- 3 1)) list
6. () list (empty list or NIL)
7. ( () () ) list (list containing 2 empty lists)




LISP as an Interpreter
• The interpreter examines source program in a repeated
loop, called the “read-evaluate-print” loop.
• The loop reads the program code, evaluates it, and
prints the values returned by the program.
• The interpreter signals its readiness to accept code for
execution by printing a prompt such as the > symbol.
e.g. > (+ 5 6 9) ; sum of three numbers
20
>




LISP as an Interpreter
• The words beyond the semicolon are COMMENTS.
• LISP can read procedure definitions and other
information from the designated file:
e.g. >(load "c:\\ lisp\\ myprog.lsp")
• To exit from LISP:
>(exit)




LISP Primitives
Primitive Name Action
+ Adds numbers.
- Subtracts numbers.
* Multiplies numbers
Procedures that come with LISP are called PRIMITIVES.
Thus the following are all LISP primitives.
* Multiplies numbers
/ Divides numbers.
MAX Finds the largest number.
MIN Finds the smallest number.
Example
>(+ 1 2 3)
6 ;LISP returns 6 because 1+2+3=6




Note
• The plus sign comes before the numbers, not in between
– prefix notation.
• In LISP, the symbol that names the thing to do is called
the procedure name.
• Whenever a list is used to specify computation, a
procedure name is always the first element of the list. procedure name is always the first element of the list.
• The rest of the elements in the list are the things to work
on. They are called arguments.
• In the previous example the procedure name is + and
the arguments are 1,2, and 3.




Some more examples
>(MAX 3 6 9 1 6 9 5)
9
>(MIN 3 6 9 1 6 9 5)
1
>(+ (- 5 3) (/ 12 6))
4
>(* (MAX 3 4 5) (MIN 3 4 5))
15
>(* 2 PI 3)
18.8496




SETF Primitive
• Assign a value to a symbol (SET Field).
• Returns the 2
nd
argument as its value.
• Side effect: Assigning the value of its 2
nd
argument to its
1
st
argument.
Example
>(SETF E 2.72)
2.72
>E
2.72




Another example
>(SETF ab-list ‘(a b))
(A B)
>ab-list
(A B)
>(SETF ab-list ‘(c d e))
(C D E)
>ab-list
(C D E)
• Note that SEFT can accept multiple symbol-value pairs
but only the value of the final argument is returned.




Note
• Binding is reserving a place in computer memory to store
a value for a symbol. LISP binds symbols as they are
encountered.
• Assignment is storing a value in that place (using SETF). • Assignment is storing a value in that place (using SETF).
• Evaluation is recovering a value from that place.




Note
• To study how to create new data, to get at old data, and
to change old data.
• Consequently, for any kind of data, there are three
groups of procedures: groups of procedures:
Procedure Type Purpose
Constructors Create new data.
Selectors Get at old data.
Mutators Change old data.




List Selectors
Selector Purpose
FIRST Return 1
st
element of the list.
REST Return list after removing the first element.
LAST Return list after removing all but one element.
BUTLAST Return list after removing the last n elements BUTLAST Return list after removing the last n elements
of a list, with the 2
nd
argument determining the
exact number.
NTHCDR Return list after removing the first n elements
of a list, with the 1
st
argument determining the
exact number
LENGTH Return the number of top-level elements in a
list.




Example
>(setf mylist ‘(fast computers are nice))
(FAST COMPUTERS ARE NICE)
>(first mylist)
FAST
>(rest mylist)
(COMPUTERS ARE NICE)
>(last mylist)
(NICE)




Example
>(butlast mylist 2)
(FAST COMPUTERS)
>(nthcdr 2 mylist)
(ARE NICE)
>(length mylist) >(length mylist)
4
>(first (rest ‘(A B C))
B




Quoting Stop Evaluation
• How can LISP know which is a specification of function
call and which is a data item?
• For example,
>(rest (a b c ))
• 'a' may be some sort of user-defined function.
• Should LISP evaluate it or should it just regard it as
data?
• You can specify where to stop evaluation by adding a
single-quote character '.
• Expression after the quote character, ', will be regarded
as data and will not be evaluated.




Quoting Stop Evaluation
• For example,
>(first (rest '(a b c)))
B
>(first '(rest (a b c)))
REST
>(setf L '(first (rest (a b c)))) >(setf L '(first (rest (a b c))))
(FIRST (REST (A B C)))
>(SETF L (PHW KAP DCB))
error: unbound function - PHW




Exercises
>(first ‘(p h w))
P
>(rest ‘(b k p h))
(K P H)
>(first ‘((a b) (c d)))
(A B)
>(rest ‘((a b) (c d)))
((c d))
>(first (rest ‘((a b) (c d))))
(c d)




Exercises
>(rest (first ‘((a b) (c d))))
(B)
>(rest (first (rest ‘((a b) (c d)))))
(D)
>(first (rest (first ‘((a b) (c d)))))
B
>(rest ‘(C))
NIL
>(first ())
NIL




Exercises
>(rest ())
NIL
>(nthcdr 2 ‘(a b c))
(C)
>(butlast ‘(a b c))
(A B)
>(last ‘(a b c))
(C)
>(last ‘((a b) (c d)))
((C D))




Exercises
>(nthcdr 50 ‘(a b c))
NIL
>(butlast ‘(a b c) 50)
NIL
>(last ())
NIL
>(first (last ‘(a b c)))
C




List Constructors - CONStruct
• Takes an expression and a list and returns a new list
whose 1
st
element is the expression and whose
remaining elements are those of the old list.
Example:
>(CONS 'A '( B C)) >(CONS 'A '( B C))
(A B C)




List Constructors - CONStruct
>(SETF L ‘(A B))
(A B)
>(SETF M ‘((L M) (X Y)))
((L M) (X Y))
>(CONS L M)
((A B) (L M) (X Y))
(A B) ( (L M) (X Y))
>(cons L L)
((A B) A B)
>(cons '(a) '(b c))
((A) B C)




List Constructors - CONStruct
• You will often combine SETF and CONS as below:
(SETF <name of a list> (CONS <new element> <name
of the list>))
• Assuming L's value is (Y Z)
>(SETF L (CONS 'X L))
(X Y Z) (X Y Z)
>L
(X Y Z)




List Constructors - CONStruct
• Note that L's OLD value is found, then the CONS makes
a NEW list, and then SETF assigns the NEW list to the
same symbol, L:
• Without SETF, L's value is not changed after CONS:
>(CONS 'X L)
(X Y Z)
>L
(Y Z)




List Constructors - APPEND
• Combines the elements of all lists supplied as
arguments.
>(APPEND '(A B C) '(X Y Z))
(A B C X Y Z)
>(CONS '(A B C) '(X Y Z))
((A B C) X Y Z)
• Comparing above both result:
– APPEND makes a list out of all the elements in its
arguments.
– CONS adds its first argument to its second argument,
a list.




Another example
>(cons '(a b c) '())
((A B C))
>(append '(a b c) '())
(A B C)
>(append '(a b c) '(())) >(append '(a b c) '(()))
(A B C NIL)




List Constructors - LIST
• Make a list out of its arguments.
• Each “argument value” becomes an element of the new
list.
• Example
>(LIST 'A 'B 'C) >(LIST 'A 'B 'C)
(A B C)
>(list 'a 'b '(c d))
(A B (C D))




List Constructors - LIST
• ASSUMING PI's value is 3.14
>(list 2 PI 3)
(2 3.14 3)
>(list 2 'PI 3)
(2 PI 3) (2 PI 3)
• Another example,
>(setf obstacles (list 'one 'two))
(ONE TWO)
>obstacles
(ONE TWO)




List Constructors - REVERSE
• Reverse the order of the top-level elements of a list.
• For example,
>(REVERSE '(A B C))
(C B A)
• Note, however, that REVERSE does not reverse the
individual elements of a list when those elements are
lists:
• For example
>(REVERSE '((A B) (L M) (X Y)))
((X Y) (L M) (A B))




Exercises
>(cons '(a b c)'())
((A B C))
>(append '(a b c)'())
(A B C)
>(list '(a b c)'())
((A B C) NIL) ((A B C) NIL)
Assume L's value is (A B C), M's value is (X Y Z)
>(list L M)
((A B C)(X Y Z))
>(list 'L M)
(L (X Y Z))




Exercises
>(list L 'M)
((A B C) M)
>(append L M)
(A B C X Y Z)
>(setf M (cons 'this (setf L '(is a list))))
(THIS IS A LIST) (THIS IS A LIST)
>L
(IS A LIST)
>M
(THIS IS A LIST)




Exercises
>(cons L L)
((IS A LIST) IS A LIST)
>(list L L)
((IS A LIST) (IS A LIST))
>(append L L)
(IS A LIST IS A LIST) (IS A LIST IS A LIST)
>(reverse '(a b c))
(C B A)
>(reverse '((a) (b) (c)))
((C) (B) (A))
>(reverse '((a b c)))
((A B C))




Predicates and Conditionals
• A predicate is a procedure that returns a value
that is either true (T) or false (NIL).




Equality Predicates
• EQUAL - Are the 2 arguments the same expr (list or
atom)?
• EQL - Are the 2 arguments the same symbol or number?
• EQ - Are the 2 arguments the same symbol? • EQ - Are the 2 arguments the same symbol?
• = - Are the 2 arguments the same number?




Equality Predicates
>(setf abc-list '(a b c) one 1 two 2 plus '+ minus '-)
-
>(equal abc-list '(a b c))
T
>(equal one 2)
NIL
>(equal abc-list one)
NIL
>(equal plus minus)
NIL




Equality Predicates
>(eql plus '+)
T
>(eq minus -1)
NIL
>(= one 'a)
error: not a number – A
>(eql 4 4.0) >(eql 4 4.0)
NIL
>(eql 4 4)
T
>(= 4 4.0)
T




Membership Predicates
• The MEMBER predicate test to see if its 1
st
argument is
an (top level) element of its 2
nd
argument.
– MEMBER returns what is left in the list when the
matching symbol is encountered.
– MEMBER returns NIL if the 1
st
argument is not a top – MEMBER returns NIL if the 1
st
argument is not a top
level element of the 2
nd
element.




Membership Predicates
>(setf sentence '(tell me about your mother please))
(tell me about your mother please)
>(member 'mother sentence)
(MOTHER PLEASE)
>(member 'father sentence) >(member 'father sentence)
NIL
>(MEMBER 'MOTHER '((FATHER SON) (MOTHER
DAUGHTER)))
NIL




Membership Predicates
• MEMBER normally tests things with a predicate that
works with symbols only. If the first argument to
MEMBER is not a symbol, you must modify slightly what
you write; otherwise MEMBER won't work as you expect.
>(SETF PAIRS '((FATHER SON) (MOTHER DAUGHTER)))
((FATHER SON) (MOTHER DAUGHTER)) ((FATHER SON) (MOTHER DAUGHTER))
>(member '(father son) pairs)
NIL
>(MEMBER '(FATHER SON) PAIRS :TEST 'EQUAL)
T




Data Types Predicates
• ATOM - Is it an atom?
• NUMBERP - Is it a number?
• SYMBOLP - Is it a symbol?
• LISTP - Is it a list?




Examples
>(atom 'pi)
T
>(atom pi)
T
>(numberp 'pi)
NIL
>(numberp pi) >(numberp pi)
T
>(symbolp 'pi)
T
>(symbolp pi)
NIL




Examples
>(atom nil)
T
>(atom ())
T
>(symbolp nil)
TT
>(symbolp ())
T
>(listp nil)
T
>(listp ())
T




Empty-List Predicates
• NULL
Is the argument an empty list ?
• ENDP
Is the argument, which must be a list, an empty list ?




Empty-List Predicates
>(null ())
T
>(endp nil)
T
>(null '(a b c))
NIL NIL
>(endp '(a b c))
NIL
>(null 'a-symbol)
NIL
>(endp 'a-symbol)
error: bad argument type – A-SYMBOL




Number Predicates
• NUMBERP Is it a number?
• ZEROP Is it zero?
• PLUSP Is it positive?
• MINUSP Is it negative?
• EVENP Is it even?
• ODDP Is it odd? • ODDP Is it odd?
• > Are they in descending order?
• < Are they in ascending order?




Examples
>(setf zero 0 one 1 two 2 three 3 four 4)
4
>(setf digits (list one two three four))
(1 2 3 4)
>(numberp 4)
TT
>(numberp four)
T
>(numberp 'four)
NIL




Examples
>(numberp digits)
NIL
>(numberp 'digits)
NIL
>(zerop zero)
TT
>(zerop 'zero)
error: bad argument type : ZERO
>(zerop four)
NIL
>(plusp one)
T




Examples
>(plusp (- one))
NIL
>(plusp zero)
NIL
>(evenp (* 9 5 3 2 1))
T
>(evenp (* 10 8 6 4 2))
T
>(> four two)
T




Examples
>(> two four)
NIL
>(> three two one)
T
>(> three one two) >(> three one two)
NIL
>(> 'four 'two)
error: bad argument type - FOUR




Combining Predicates - AND
• AND returns NIL if any of its argument evaluates to NIL.
• The arguments are evaluated from left-to-right, if any
evaluates to NIL, none of the remaining is evaluated,
and the value returned is NIL.
• If all arguments evaluate to non-NIL values, the value • If all arguments evaluate to non-NIL values, the value
returned by the AND is the value of the last argument.
• It takes any number of arguments.




Combining Predicates - AND
>(setf pets '(dog cat))
(DOG CAT)
>(and (member 'dog pets) (member 'tiger pets))
NIL
>(and (member 'dog pets) (member 'cat pets))
(CAT) (CAT)




Combining Predicates - AND
>(setf result NIL pi 3.14)
3.14
>(AND (LISTP PI) (SETF RESULT 'SET-IN-FIRST-AND))
NIL
>RESULT
NIL NIL
>(AND (NUMBERP PI) (SETF RESULT 'SET-IN-SECOND-
AND))
SET-IN-SECOND-AND
>RESULT
SET-IN-SECOND-AND




Combining Predicates - OR
• OR returns NIL if all of its arguments evaluates to NIL.
• The arguments are evaluated from left to right, if any
evaluates to non-NIL, none of the remaining is
evaluated, and the value returned is that non-NIL value.
• If all arguments evaluates to NIL, the value returned by
OR is NIL.
• It takes any number of arguments.




Combining Predicates - OR
>(setf pets '(dog cat))
(DOG CAT)
>(or (member 'dingo pets) (member 'tiger pets))
NIL NIL
>(or (member 'dog pets) (member 'cat pets))
(DOG CAT)




Combining Predicates - OR
>(setf result NIL pi 3.14)
3.14
>(OR (NUMBERP PI) (SETF RESULT 'SET-IN-FIRST-
OR))
T
>RESULT >RESULT
NIL
>(OR (LISTP PI) (SETF RESULT 'SET-IN-SECOND-OR))
SET-IN-SECOND-OR
>RESULT
SET-IN-SECOND-OR




Combining Predicates - NOT
• NOT just turns non-NIL to NIL and NIL to T
• Example
>(not 'dog)
NIL
>(setf pets '(dog cat)) >(setf pets '(dog cat))
(DOG CAT)
>(not (member 'dog pets))
NIL
>(not (member 'tiger pets))
T




Simple Branching Primitives - IF
(IF <test> <then form> <else form>)
• IF returns the value of its <then form> when <test>
evaluates to T or ANYTHING other than NIL; otherwise,
IF returns the value of its <else form>.
• Assuming TRIGGER'S value is T.
>(IF TRIGGER 'ITS-TRUE 'ITS-FALSE) >(IF TRIGGER 'ITS-TRUE 'ITS-FALSE)
ITS-TRUE
• Now assume TRIGGER's value is NIL:
>(IF TRIGGER 'ITS-TRUE 'ITS-FALSE)
ITS-FALSE




Simple Branching Primitives - IF
>(setf day-or-date 'monday)
MONDAY
>(if (symbolp day-or-date) 'day 'date)
DAY
>(setf day-or-date 9)
9
>(if (symbolp day-or-date) 'day 'date)
DATE
• If there's no <else-form> and if <test> evaluates to NIL,
NIL will be returned.




Simple Branching Primitives - WHEN
(WHEN <test> <then form>)
• WHEN returns the value of <then form> when <test>
evaluates to ANYTHING other than NIL.
• Example
>(WHEN T 'ITS-TRUE)
ITS-TRUE
• When WHEN's first argument evaluates to NIL, WHEN
returns nil:
>(WHEN NIL 'ITS-TRUE)
NIL




Simple Branching Primitives - WHEN
>(setf high 98 temperature 102)
102
>(when (> temperature high) (setf high temperature))
102
>high
102




Simple Branching Primitives - UNLESS
(UNLESS <test> <else form>)
• UNLESS returns the value of <else form> when <test>
evaluates to NIL.
• Example
>(UNLESS NIL 'ITS-FALSE) >(UNLESS NIL 'ITS-FALSE)
ITS-FALSE
• When UNLESS's first argument evaluates to non-NIL,
UNLESS returns NIL:
>(UNLESS T 'ITS-FALSE)
NIL




Simple Branching Primitives - UNLESS
>(setf high 98 temperature 102)
102
>(unless (< temperature high) (setf high temperature))
102
>high
102




General Branching Primitives - COND
(COND (<test 1> <consequent 1-1> <consequent 1-2> ...)
(<test 2) <consequent 2-1> <consequent 2-2> ...)
...
...
(<test m> <consequent m-1> <consequent m-2> ...))




General Branching Primitives - COND
• The symbol COND is followed by clauses. Each clause
contains a test and zero or more forms called
consequent.
• COND moves through the clauses, evaluating the test
forms, until a test form evaluates to non-NIL. This clause
is "triggered" and its consequent forms are evaluated. is "triggered" and its consequent forms are evaluated.
• The value returned by COND is the value of the last
consequent form in the triggered clause.
• If all test forms are NIL, the value returned by COND is
also NIL.




General Branching Primitives - COND
>(cond ((= N 0) (setf answer '(value is zero)))
((> N 1) (setf answer '(value is positive)))
(T (setf answer '(value is negative))))




General Branching Primitives - CASE
(CASE <key form>
(<key 1> <consequent 1-1> <consequent 1-2> ...)
(<key 2> <consequent 2-1> <consequent 2-2> ...)
...
...
(<key m> <consequent m-1> <consequent m-2) ...)) (<key m> <consequent m-1> <consequent m-2) ...))




General Branching Primitives - CASE
• CASE checks the <key form> against the <key> in each
clause using "EQL" until a matching is found. The
corresponding clause is then triggered and all its
consequent are evaluated.
• The value returned by CASE is the value of the last • The value returned by CASE is the value of the last
consequent form in the triggered clause.
• If no matching occurs, the value returned by CASE is
NIL.




General Branching Primitives - CASE
>(setf thing 'point r 1)
1
>(case thing
(circle (* pi r))
(sphere (* 4 pi r r)
(otherwise 0)) (otherwise 0))
NIL
• The last clause in the above example is called a Catch-
all clause.
• With a Catch-all clause, the final clause is used when
none of the others are triggered.




General Branching Primitives - CASE
• If the <key> in a clause is a list, not an atom, CASE
checks the <key form> against the <key> list using
MEMBER
• Example
>(setf thing 'ball r 1)
1
>(case thing >(case thing
((circle wheel) (* pi r r))
((sphere ball) (* 4 pi r r))
(otherwise 0))
12.566




Procedure Definition and Binding - DEFUN
• LISP encourages you to create small, easily debugged
procedures.
• DEFUN DEfine FUNction
(defun <function name> (<parameters>)
<forms>) <forms>)
• The DEFUN function establishes a function definition as
its side-effect.
• The value returned by DEFUN is the function name.




Procedure Definition and Binding - DEFUN
>(DEFUN BOTH-ENDS ;Procedure's name is BOTH-ENDS.
(L) ;The parameter is L.
(CONS (FIRST L) (LAST L)) ;The form.
) ;End the DEFUN primitive
BOTH-ENDS ;LISP returns the function name
>(BOTH-ENDS '(A B C D E)) >(BOTH-ENDS '(A B C D E))
(A E)
>(BOTH-ENDS '(START L M N FINISH))
(START FINISH)




Procedure Definition and Binding - DEFUN
• When calling a function, the value returned by that
function is the value of the last form in its body.
>(defun cons-tail (tail alist) ;function name, parameters
(setf count (+ count 1)) ;first form
(append alist (list tail))) ;last form
CONS-TAIL
>(cons-tail 'pear '(apple orange))
(APPLE ORANGE PEAR)




Procedure Definition and Binding - DEFUN
• PARAMETER VARIABLES bindings are established
when a function is entered. They are isolated from other
variable bindings outside the function.
• Example:
>(setf L '(a b c))
(A B C)
>(defun both-ends (L) >(defun both-ends (L)
(cons (first L)(last L)))
BOTH-ENDS
>(both-ends '(d e f))
(D F)
>L
(A B C)




Procedure Definition and Binding - DEFUN
• NON-PARAMETER variables are not isolated from
variables outside the function.
• Example:
>(setf count 0)
0
>(defun cons-tail (tail alist)
(setf count (+ count 1))
(append alist (list tail)))
CONS-TAIL
>(cons-tail 'a '(b c))
(B C A)
>count
1




Repetition
• Many LISP procedures work by repeating a particular action
over and over until a certain condition is met.
++--- --- Recursion Recursion
To repeat To repeat ----- -----| + | +--- --- Using DO Using DO
++--- ---Iteration Iteration---- ----||
++--- ---Using MAPCAR Using MAPCAR




Repeating by Recursion
(DEFUN COUNT-ELEMENTS (L)
(IF (ENDP L) 0
(+ 1 (COUNT-ELEMENTS (REST L)))
)
)
• The definition of COUNT-ELEMENTS involves a form using
COUNT-ELEMENTS itself. Such procedures are said to be COUNT-ELEMENTS itself. Such procedures are said to be
RECURSIVE.
• Many recursive procedures solve problems by breaking up a
list, working on its pieces, and combining the results of working
on those pieces.




Repeating by Iteration
• You will often want to do a computation over and over until
one of the two following criteria is satisfied:
– A test has been satisfied.
– All elements in a list have been worked on.




Repeating by Iteration - DOTIMES
(dotimes (<count parameter> <upper-bound form> <result form>)
<body>)
• When DOTIMES is entered, the <upper-bound form> is
evaluated, producing a number of n.
• The <count parameter> is then assigned from 0 to n-1, one • The <count parameter> is then assigned from 0 to n-1, one
after another.
• For each value, the body is executed once.
• On exit, the <count parameter>'s binding is eliminated and the
<result form> is evaluated as the return value of DOTIMES.




>(setf result 1)
1
>(dotimes (count 5 result)
(setf result (* (+ 1 count) result)))
120 120




Repeating by Iteration - DOLIST
(dolist (<element parameter> <list form> <result form>)
<body>)
• When DOLIST is entered, the <list form> is evaluated,
producing a list of elements.
• The elements in the list are then assigned, one after another, to • The elements in the list are then assigned, one after another, to
the element parameter.
• For each value, the body is executed once.
• On exit, the element parameter's binding is eliminated and the
<result form> is evaluated as the return value of DOLIST.




Repeating by Iteration - DOLIST
>(setf foo '(a b (c d)) bar '())
NIL
>(DOLIST (ele foo bar)
(SETF bar (CONS ele bar))))
((C D) B A)
• Whenever a (RETURN <expression>) is encountered in
DOTIMES or DOLIST, computation will be terminated
immediately.
• The <expression> is evaluated as the return value of the
terminated DOTIMES and DOLIST form.




Repeating by Iteration - DO
• DO expressions have the following parts:
– A list of parameter specifications, each of which creates,
sets, and resets one of the DO form's parameters:
(<parameter> <initial value> <reset form>)
– A test and return clause that determines when to stop the
iteration and specifies the DO form's value once stopped: iteration and specifies the DO form's value once stopped:
(<trigger> <side effect forms, if any> <value form>)
– A body that consists of DO's subforms, which are evaluated
over and over until the DO is stopped:
<body form>




Repeating by Iteration - DO
• The syntax of DO:
(DO ((<parameter 1> <initial value 1> <update form 1>)
(<parameter 2> <initial value 2> <update form 2>) ...
(<parameter n> <initial value n> <update form n>))
(<test form> <result form>)
<body form>) <body form>)




Repeating by Iteration - DO
>(DO ((L '(THIS IS A LIST) (REST L))
(RESULT NIL))
((NULL L) RESULT)
(SETF RESULT (CONS (FIRST L) RESULT)))
(LIST A IS THIS)
>(defun do-exp (m n)
(do ((result 1) (exponent n (- exponent 1)))
((zerop exponent) result)
(setf result (* m result))))




Repeating by Iteration - DO
• Whenever (RETURN <expression>) is encountered, DO is
terminated immediately. <expresion> is evaluated as the return
value of the terminated DO.
• All initializations and updates are done in parallel, i.e. all initial
forms are evaluated before bindings and all update forms are
evaluated before assignments. evaluated before assignments.




Repeating by Iteration - LOOP
(loop <body>)
• The body is evaluated over and over until a (RETURN
<expression>) is encountered.
• Again the <expression> is evaluated as the return value of the
terminated LOOP. terminated LOOP.




Input-Output
• read
– read takes no arguments.
– When read appears in a procedure, processing halts
until a single s-expression is entered from the keyboard.
The s-expression is then returned as the value of read
and processing continues. and processing continues.
e.g. >(+ 5 (read))
6
11




Input-Output
• print
– Takes one argument.
– It prints the argument as it is received, and then returns
the argument.
– This makes it possible to print something and also pass
the same thing on to another function as an argument.
– When print is used to print an expression, it argument is – When print is used to print an expression, it argument is
preceded by the carriage-return and line-feed characters
and is preceded by a space.
e.g. >(print ‘(a b c))
(A B C)
(A B C)
>(print “hello there”)
“hello there”
“hello there”




Input-Output
• prin1
– Same as print except that the new-line characters
and space are not provided.
e.g. >((prin1 ‘(hello))(prin1 ‘(hello)))
(HELLO)(HELLO)
• princ • princ
– It is the same as prin1 except it does not print the
unwanted quotation marks.
e.g. >(princ “hello there”)
hello there “hello there”




Input-Output
• terpri
– Takes no arguments.
– It introduces a new-line (carriage return and line feed)
wherever it appears and then returns nil.
e.g. >(defun circle-area()
(terpri)
(princ “Please enter the radius:”)
(setq radius (read)) (setq radius (read))
(princ “The area of the circle is:”)
(princ (* 3.14159 radius radius)))
CIRCLE-AREA
>(circle-area)
Please enter the radius: 4
The area of the circle is: 50.2656




Input-Output
• format
(format <destination> <string> arg1 arg2…).
• Destination specifies where the output is to be
directed, like to the monitor or some other
external file.
• If destination is t the default output is monitor. • If destination is t the default output is monitor.
• String is the desired output string, but intermixed
with format directives which specify how each
argument is to be represented.
• Directives appear in the string in the same order
the arguments are to be printed.
• Each directive is preceded with a tilde character
(~) to identify it as a directive.




Input-Output
• The most common directives below:
– ~A The argument is printed as though princ were used.
– ~S The argument is printed as though prin1 were used.
– ~D The argument which must be an integer is printed as
a decimal number.
– ~F The argument which must be a floating-point number
is printed as a decimal floating-point number.
– ~C The argument is printed as character output.
– % A new-line is printed.




Input-Output
• The field widths for appropriate argument values are
specified with an integer immediately following the tilde
symbol.
e.g. ~5D specifies an integer field of width 5.
e.g.
>(format t “Circle radius=~2F~%Circle area=~3F” x y) >(format t “Circle radius=~2F~%Circle area=~3F” x y)
Circle radius=3.0
Circle area=9.42
• x and y have been bound to floating-point numbers 3.0 and
9.42 respectively.




Transformation Primitive - MAPCAR
(MAPCAR #'<procedure-name> <list-of-things-to-work-on>)
• MAPCAR takes two arguments: a procedure name and a list
of things to work on.
• The result is the list of values you would have if you worked
on each element in the given list with the given procedure.
• Example: • Example:
>(MAPCAR #'FIRST '((A B C) (X Y Z)))
(A X)
• FIRST's result, working on the first element, (A B C), is A.
• FIRST's result, working on the second element, (X Y Z), is X.
• All the results of FIRST, made into a list, is (A X).




Transformation Primitive - MAPCAR
• If the transformation procedure requires more than 1
parameter, there must be a corresponding number of lists.
• For example,
>(MAPCAR #'= '(1 2 3) '(3 2 1))
(NIL T NIL) (NIL T NIL)
• The transformation procedure is applied to the FIRST element
of each list, then the SECOND element of each list, and so on
until no more elements remain in one of the lists.
>(MAPCAR #'list '(a b c) '(1 2) '(x y z))
((A 1 X) (B 2 Y))




Filtering Primitive – REMOVE-IF, REMOVE-IF-NOT
(remove-if #'<filtering-procedure-name>
<list-of-elements-to-be-filtered>)
(remove-if-not #'<filtering-procedure-name>
<list-of-elements-to-be-filtered>)
• REMOVE-IF eliminates all elements that satisfy the filtering
predicate.
• REMOVE-IF-NOT eliminates all elements that do not satisfy
the filtering predicate.
• Example:
>(REMOVE-IF #'evenp '(1 2 3 4 5))
(1 3 5)
>(REMOVE-IF-NOT #'evenp '(1 2 3 4 5))
(2 4)




Counting Primitive - COUNT-IF
(count-if #'<filtering-procedure>
<list-of-elements-to-be-counted>)
• COUNT-IF provides a way to count the number of elements in
a list which satisfy a given condition.
• For example,
>(count-if #'evenp '(1 2 3 4 5)) >(count-if #'evenp '(1 2 3 4 5))
2




Finding Primitive - FIND-IF
(find-if #'<test-procedure>
<list-of-elements-to-be-tested>)
• FIND-IF finds the first element in the list which satisfy the
testing predicate.
• For example,
>(find-if #'evenp '(1 2 3 4 5 6))
22




Property List
• A symbol may have property values:
symbol parent property children property spouse property
====== =============== ================= ===============
PATRICK (ROBERT DOROTHY) (SARAH) (CANDY)




Retrieving a property value
(GET <symbol> <property name>)
• Example:
>(get 'patrick 'parent)
(ROBERT DOROTHY)
>(get 'patrick 'grandparent)
NIL ;;because no such property exists NIL ;;because no such property exists




Storing a property value
(SETF (GET <symbol> <property name>) <property value>)
• Example:
>(setf (get 'patrick 'parent) '(albert dora))
(ALBERT DORA)
>(get 'patrick 'parent)
(ALBERT DORA) (ALBERT DORA)




Removing a property value
(REMPROP <symbol> <property name>)
• Example:
>(remprop 'patrick 'spouse)
T
>(get 'patrick 'spouse)
NIL
• Note: If a symbol is a property list, only its properties have • Note: If a symbol is a property list, only its properties have
values. The symbol itself does not have any value:
>patrick
ERROR ;; unbound variable
>(setf albert 'patrick)
PATRICK
>(setf albert patrick)
ERROR



You are using demo version Please purchase full version from www.technocomsolutions.com

Introduction
• There are several variations of LISP including FRANZLISP, INTERLISP, MACLISP, QLISP, SCHEME, and COMMON LISP. • The COMMON LISP version is the most recent, more portable and easier to maintain. • Like most traditional programming languages, LISP is procedural i.e. LISP programs describe HOW to perform an algorithm.

You are using demo version Please purchase full version from www.technocomsolutions.com

Introduction
• LISP is a FUNCTIONAL language. Its syntax and semantics are derived from the mathematical theory of recursive functions. Everything in LISP is a function. • A function is a procedure that takes in one or more input arguments and returns only one value, with no side effect. g(a, b) = a + b • LISP is NOT a 'pure' functional language some of its functions produce side effects, e.g. SETF -

You are using demo version Please purchase full version from www.com The bowls analogy • To understand LISTS and ATOMS. like those used to store things in a refrigerator. • Often refrigerator bowls are made to fit inside one another so that they are easy to store. ( ( ( ) ) ) ( ( ) ) ( ) +-----------------+ +-------+ +---+ . • The easiest way to understand lists and atoms is to do analogy with bowls.technocomsolutions.

technocomsolutions.com The bowls analogy We can put the small bowl inside the medium one: ( ( ) ) ( +---+ ) +-------+ Then we can put the combination of the small and medium bowls inside the big bowl: ( ( ( ) ) ) ( ( +---+ ) ) ( +-------+ ) +-----------------+ Here we can say that the small bowl is empty. and the big bowl contains the medium bowl. . the medium bowl contains the small bowl.You are using demo version Please purchase full version from www.

we can put both the small bowl and the medium bowl inside the big bowl this way: ( ( ) ) ( ( ) ( ) ) ( +-------+ +---+ ) +-----------------+ Here we say that both the small bowl and the medium bowl are empty and that the big bowl contains both the small bowl and the medium bowl. .You are using demo version Please purchase full version from www.technocomsolutions.com The bowls analogy Alternatively.

You are using demo version Please purchase full version from www. the medium bowl now contains two apples and one pear.technocomsolutions. represented here by As for the Apples and a P for the Pear: ( ( ) ) ( ( A A P ) ( ) ) ( +-------+ +---+ ) +-----------------+ The small bowl is still empty.com The bowls analogy We can also put some fruit in the bowls. . and the big bowl still contains the small and medium bowls.

and the other is empty.technocomsolutions. too.You are using demo version Please purchase full version from www. . The large bowl contains both a medium bowl and another pear. The small bowl contains a pear.com The bowls analogy ( ( ( ) ( ( ( A A P ) +-------+ ) ) P ) ) ) ( P ) +---+ ( +-------+ +-----------------+ Now there are two medium bowls: one contains two apples and one pear.

lists can contain things that are not containers. lists can be empty. • LISTS are like BOWLS.You are using demo version Please purchase full version from www. . • Like bowls. lists can contain other lists.technocomsolutions. • Like bowls. • Like bowls.com LISTS and ATOMS • The basic data objects in LISP are LISTS and ATOMS. • ATOMS are like the things people store in bowls.

com LISTS and ATOMS One bowl inside another inside another: ( ( ( ) ) ) ( ( +---+ ) ) ( +-------+ ) +-----------------+ One list inside another inside another: ( (( )) ) Here we can say that the inside list is empty. the combination is. inside still another list.technocomsolutions. in turn.You are using demo version Please purchase full version from www. the empty list is inside another list. .

technocomsolutions.com LISTS and ATOMS ( ( ) ) ( ( A A P ) ( ) ) ( +-------+ +---+ ) +-----------------+ List is: ( ( AA P ) ( ) ) One list is empty. called atoms. just as there is a bowl containing two bowls. just as one bowl was. There is a list containing two lists.You are using demo version Please purchase full version from www. just as one bowl contains three pieces of fruit. . Another list contains three things.

which have obvious meanings are called ATOMS.technocomsolutions. • Atoms like FIRST. . are called NUMERIC ATOMS. etc. +. 3. are called SYMBOLIC ATOMS. etc.You are using demo version Please purchase full version from www.14. • Atoms like 27. FOO. +. • Indivisible things like 27.com Basic Data Types of LISP • Every expression in LISP is either an atom or a list. FOO. FIRST.

• Both atoms and lists are called SYMBOLIC EXPRESSIONS or s-expression. • Elements of a list are atoms or lists. followed by a right parenthesis: ( a b c (d e) ) • Elements of a list are separated by space.You are using demo version Please purchase full version from www.technocomsolutions.com Basic Data Types of LISP • A list consists of a left parenthesis. . followed by zero or more elements.

list .com +-.number | +-.atom + | | Expression + +-+-.symbol | +-.technocomsolutions.You are using demo version Please purchase full version from www.

4. 5.3 1)) () ( () () ) atom list neither list list list (empty list or NIL) list (list containing 2 empty lists) . ATOM (THIS IS AN ATOM) ((A B) (C D)) 3 (3) (LIST 3) (/ (+ 3 1) (.com Exercises 1. 3. 2.technocomsolutions. 6.You are using demo version Please purchase full version from www. 7.

You are using demo version Please purchase full version from www.technocomsolutions. and prints the values returned by the program.g. e. sum of three numbers . • The interpreter signals its readiness to accept code for execution by printing a prompt such as the > symbol.com LISP as an Interpreter • The interpreter examines source program in a repeated loop. evaluates it. • The loop reads the program code. called the “read-evaluate-print” loop. > (+ 5 6 9) 20 > .

• LISP can read procedure definitions and other information from the designated file: e. >(load "c:\\ lisp\\ myprog.You are using demo version Please purchase full version from www.com LISP as an Interpreter • The words beyond the semicolon are COMMENTS.lsp") • To exit from LISP: >(exit) .technocomsolutions.g.

com LISP Primitives Procedures that come with LISP are called PRIMITIVES.technocomsolutions. Finds the smallest number.LISP returns 6 because 1+2+3=6 . Primitive Name Action + Adds numbers. Thus the following are all LISP primitives. * / MAX MIN Example >(+ 1 2 3) 6 Subtracts numbers. Finds the largest number.You are using demo version Please purchase full version from www. . Multiplies numbers Divides numbers.

a procedure name is always the first element of the list. • The rest of the elements in the list are the things to work on.2. They are called arguments.technocomsolutions. • In the previous example the procedure name is + and the arguments are 1. • In LISP. • Whenever a list is used to specify computation.You are using demo version Please purchase full version from www. the symbol that names the thing to do is called the procedure name.com Note • The plus sign comes before the numbers. not in between – prefix notation. and 3. .

technocomsolutions.com Some more examples >(MAX 3 6 9 1 6 9 5) 9 >(MIN 3 6 9 1 6 9 5) 1 >(+ (.You are using demo version Please purchase full version from www.8496 .5 3) (/ 12 6)) 4 >(* (MAX 3 4 5) (MIN 3 4 5)) 15 >(* 2 PI 3) 18.

Example >(SETF E 2. • Returns the 2nd argument as its value.72 >E 2.technocomsolutions. • Side effect: Assigning the value of its 2nd argument to its 1st argument.72) 2.72 .com SETF Primitive • Assign a value to a symbol (SET Field).You are using demo version Please purchase full version from www.

You are using demo version Please purchase full version from www.technocomsolutions.com

Another example
>(SETF ab-list ‘(a b)) (A B) >ab-list (A B) >(SETF ab-list ‘(c d e)) (C D E) >ab-list (C D E) • Note that SEFT can accept multiple symbol-value pairs but only the value of the final argument is returned.

You are using demo version Please purchase full version from www.technocomsolutions.com

Note
• Binding is reserving a place in computer memory to store a value for a symbol. LISP binds symbols as they are encountered. • Assignment is storing a value in that place (using SETF). • Evaluation is recovering a value from that place.

You are using demo version Please purchase full version from www.technocomsolutions.com

Note
• To study how to create new data, to get at old data, and to change old data. • Consequently, for any kind of data, there are three groups of procedures: Procedure Type Constructors Selectors Mutators Purpose Create new data. Get at old data. Change old data.

Return list after removing the first element. with the 1st argument determining the exact number Return the number of top-level elements in a list.technocomsolutions. Return list after removing the first n elements of a list. NTHCDR LENGTH . Return list after removing the last n elements of a list.You are using demo version Please purchase full version from www.com List Selectors Selector FIRST REST LAST BUTLAST Purpose Return 1st element of the list. Return list after removing all but one element. with the 2nd argument determining the exact number.

You are using demo version Please purchase full version from www.technocomsolutions.com Example >(setf mylist ‘(fast computers are nice)) (FAST COMPUTERS ARE NICE) >(first mylist) FAST >(rest mylist) (COMPUTERS ARE NICE) >(last mylist) (NICE) .

technocomsolutions.com Example >(butlast mylist 2) (FAST COMPUTERS) >(nthcdr 2 mylist) (ARE NICE) >(length mylist) 4 >(first (rest ‘(A B C)) B .You are using demo version Please purchase full version from www.

• Should LISP evaluate it or should it just regard it as data? • You can specify where to stop evaluation by adding a single-quote character '. '.technocomsolutions. • Expression after the quote character. will be regarded as data and will not be evaluated. >(rest (a b c )) • 'a' may be some sort of user-defined function. .com Quoting Stop Evaluation • How can LISP know which is a specification of function call and which is a data item? • For example.You are using demo version Please purchase full version from www.

technocomsolutions.com Quoting Stop Evaluation • For example. >(first (rest '(a b c))) B >(first '(rest (a b c))) REST >(setf L '(first (rest (a b c)))) (FIRST (REST (A B C))) >(SETF L (PHW KAP DCB)) error: unbound function .PHW .You are using demo version Please purchase full version from www.

com Exercises >(first ‘(p h w)) P >(rest ‘(b k p h)) (K P H) >(first ‘((a b) (c d))) (A B) >(rest ‘((a b) (c d))) ((c d)) >(first (rest ‘((a b) (c d)))) (c d) .You are using demo version Please purchase full version from www.technocomsolutions.

com Exercises >(rest (first ‘((a b) (c d)))) (B) >(rest (first (rest ‘((a b) (c d))))) (D) >(first (rest (first ‘((a b) (c d))))) B >(rest ‘(C)) NIL >(first ()) NIL .technocomsolutions.You are using demo version Please purchase full version from www.

You are using demo version Please purchase full version from www.com Exercises >(rest ()) NIL >(nthcdr 2 ‘(a b c)) (C) >(butlast ‘(a b c)) (A B) >(last ‘(a b c)) (C) >(last ‘((a b) (c d))) ((C D)) .technocomsolutions.

You are using demo version Please purchase full version from www.com Exercises >(nthcdr 50 ‘(a b c)) NIL >(butlast ‘(a b c) 50) NIL >(last ()) NIL >(first (last ‘(a b c))) C .technocomsolutions.

com List Constructors . Example: >(CONS 'A '( B C)) (A B C) .CONStruct • Takes an expression and a list and returns a new list whose 1st element is the expression and whose remaining elements are those of the old list.You are using demo version Please purchase full version from www.technocomsolutions.

CONStruct >(SETF L ‘(A B)) (A B) >(SETF M ‘((L M) (X Y))) ((L M) (X Y)) (A B) ( >(CONS L M) ((A B) (L M) (X Y)) >(cons L L) ((A B) A B) >(cons '(a) '(b c)) ((A) B C) (L M) (X Y)) .You are using demo version Please purchase full version from www.com List Constructors .technocomsolutions.

You are using demo version Please purchase full version from www.technocomsolutions.com

List Constructors - CONStruct

• You will often combine SETF and CONS as below: (SETF <name of a list> (CONS <new element> <name of the list>)) • Assuming L's value is (Y Z) >(SETF L (CONS 'X L)) (X Y Z) >L (X Y Z)

You are using demo version Please purchase full version from www.technocomsolutions.com

List Constructors - CONStruct

• Note that L's OLD value is found, then the CONS makes a NEW list, and then SETF assigns the NEW list to the same symbol, L: • Without SETF, L's value is not changed after CONS: >(CONS 'X L) (X Y Z) >L (Y Z)

You are using demo version Please purchase full version from www.technocomsolutions.com

List Constructors - APPEND
• Combines the elements of all lists supplied as arguments. >(APPEND '(A B C) '(X Y Z)) (A B C X Y Z) >(CONS '(A B C) '(X Y Z)) ((A B C) X Y Z) • Comparing above both result: – APPEND makes a list out of all the elements in its arguments. – CONS adds its first argument to its second argument, a list.

You are using demo version Please purchase full version from www.technocomsolutions.com Another example >(cons '(a b c) '()) ((A B C)) >(append '(a b c) '()) (A B C) >(append '(a b c) '(())) (A B C NIL) .

LIST • Make a list out of its arguments. • Each “argument value” becomes an element of the new list.You are using demo version Please purchase full version from www.technocomsolutions.com List Constructors . • Example >(LIST 'A 'B 'C) (A B C) >(list 'a 'b '(c d)) (A B (C D)) .

You are using demo version Please purchase full version from www.14 3) >(list 2 'PI 3) (2 PI 3) • Another example. >(setf obstacles (list 'one 'two)) (ONE TWO) >obstacles (ONE TWO) .LIST • ASSUMING PI's value is 3.com List Constructors .technocomsolutions.14 >(list 2 PI 3) (2 3.

however. that REVERSE does not reverse the individual elements of a list when those elements are lists: • For example >(REVERSE '((A B) (L M) (X Y))) ((X Y) (L M) (A B)) . >(REVERSE '(A B C)) (C B A) • Note.com List Constructors . • For example.You are using demo version Please purchase full version from www.REVERSE • Reverse the order of the top-level elements of a list.technocomsolutions.

com Exercises >(cons '(a b c)'()) ((A B C)) >(append '(a b c)'()) (A B C) >(list '(a b c)'()) ((A B C) NIL) Assume L's value is (A B C).You are using demo version Please purchase full version from www. M's value is (X Y Z) >(list L M) ((A B C)(X Y Z)) >(list 'L M) (L (X Y Z)) .technocomsolutions.

technocomsolutions.com Exercises >(list L 'M) ((A B C) M) >(append L M) (A B C X Y Z) >(setf M (cons 'this (setf L '(is a list)))) (THIS IS A LIST) >L (IS A LIST) >M (THIS IS A LIST) .You are using demo version Please purchase full version from www.

com Exercises >(cons L L) ((IS A LIST) IS A LIST) >(list L L) ((IS A LIST) (IS A LIST)) >(append L L) (IS A LIST IS A LIST) >(reverse '(a b c)) (C B A) >(reverse '((a) (b) (c))) ((C) (B) (A)) >(reverse '((a b c))) ((A B C)) .You are using demo version Please purchase full version from www.technocomsolutions.

.technocomsolutions.You are using demo version Please purchase full version from www.com Predicates and Conditionals • A predicate is a procedure that returns a value that is either true (T) or false (NIL).

com Equality Predicates • EQUAL .Are the 2 arguments the same symbol or number? • EQ .Are the 2 arguments the same number? .You are using demo version Please purchase full version from www.technocomsolutions.Are the 2 arguments the same symbol? • = .Are the 2 arguments the same expr (list or atom)? • EQL .

You are using demo version Please purchase full version from www.com Equality Predicates >(setf abc-list '(a b c) one 1 two 2 plus '+ minus '-) >(equal abc-list '(a b c)) T >(equal one 2) NIL >(equal abc-list one) NIL >(equal plus minus) NIL .technocomsolutions.

0) NIL >(eql 4 4) T >(= 4 4.0) T .com Equality Predicates >(eql plus '+) T >(eq minus -1) NIL >(= one 'a) error: not a number – A >(eql 4 4.technocomsolutions.You are using demo version Please purchase full version from www.

technocomsolutions.You are using demo version Please purchase full version from www. . – MEMBER returns what is left in the list when the matching symbol is encountered. – MEMBER returns NIL if the 1st argument is not a top level element of the 2nd element.com Membership Predicates • The MEMBER predicate test to see if its 1st argument is an (top level) element of its 2nd argument.

com Membership Predicates >(setf sentence '(tell me about your mother please)) (tell me about your mother please) >(member 'mother sentence) (MOTHER PLEASE) >(member 'father sentence) NIL >(MEMBER NIL 'MOTHER '((FATHER SON) (MOTHER DAUGHTER))) .technocomsolutions.You are using demo version Please purchase full version from www.

>(SETF PAIRS '((FATHER SON) (MOTHER DAUGHTER))) ((FATHER SON) (MOTHER DAUGHTER)) >(member '(father son) pairs) NIL >(MEMBER '(FATHER SON) PAIRS :TEST 'EQUAL) T . you must modify slightly what you write.com Membership Predicates • MEMBER normally tests things with a predicate that works with symbols only. If the first argument to MEMBER is not a symbol.technocomsolutions. otherwise MEMBER won't work as you expect.You are using demo version Please purchase full version from www.

technocomsolutions.com Data Types Predicates • ATOM .Is it a symbol? • LISTP .You are using demo version Please purchase full version from www.Is it an atom? • NUMBERP .Is it a list? .Is it a number? • SYMBOLP .

You are using demo version Please purchase full version from www.com Examples >(atom 'pi) T >(atom pi) T >(numberp 'pi) NIL >(numberp pi) T >(symbolp 'pi) T >(symbolp pi) NIL .technocomsolutions.

You are using demo version Please purchase full version from www.technocomsolutions.com Examples >(atom nil) T >(atom ()) T >(symbolp nil) T >(symbolp ()) T >(listp nil) T >(listp ()) T .

which must be a list.You are using demo version Please purchase full version from www.technocomsolutions. an empty list ? .com Empty-List Predicates • NULL Is the argument an empty list ? • ENDP Is the argument.

technocomsolutions.com Empty-List Predicates >(null ()) T >(endp nil) T >(null '(a b c)) NIL >(endp '(a b c)) NIL >(null 'a-symbol) NIL >(endp 'a-symbol) error: bad argument type – A-SYMBOL .You are using demo version Please purchase full version from www.

technocomsolutions.com Number Predicates • • • • • • • • NUMBERP ZEROP PLUSP MINUSP EVENP ODDP > < Is it a number? Is it zero? Is it positive? Is it negative? Is it even? Is it odd? Are they in descending order? Are they in ascending order? .You are using demo version Please purchase full version from www.

technocomsolutions.com Examples >(setf zero 0 one 1 two 2 three 3 four 4) 4 >(setf digits (list one two three four)) (1 2 3 4) >(numberp 4) T >(numberp four) T >(numberp 'four) NIL .You are using demo version Please purchase full version from www.

You are using demo version Please purchase full version from www.technocomsolutions.com Examples >(numberp digits) NIL >(numberp 'digits) NIL >(zerop zero) T >(zerop 'zero) error: bad argument type : ZERO >(zerop four) NIL >(plusp one) T .

com Examples >(plusp (.You are using demo version Please purchase full version from www.technocomsolutions.one)) NIL >(plusp zero) NIL >(evenp (* 9 5 3 2 1)) T >(evenp (* 10 8 6 4 2)) T >(> four two) T .

technocomsolutions.FOUR .You are using demo version Please purchase full version from www.com Examples >(> two four) NIL >(> three two one) T >(> three one two) NIL >(> 'four 'two) error: bad argument type .

if any evaluates to NIL. . • If all arguments evaluate to non-NIL values. none of the remaining is evaluated.com Combining Predicates . the value returned by the AND is the value of the last argument.AND • AND returns NIL if any of its argument evaluates to NIL.technocomsolutions.You are using demo version Please purchase full version from www. • The arguments are evaluated from left-to-right. and the value returned is NIL. • It takes any number of arguments.

technocomsolutions.com Combining Predicates .AND >(setf pets '(dog cat)) (DOG CAT) >(and (member 'dog pets) (member 'tiger pets)) NIL >(and (member 'dog pets) (member 'cat pets)) (CAT) .You are using demo version Please purchase full version from www.

14 >(AND (LISTP PI) (SETF RESULT 'SET-IN-FIRST-AND)) NIL >RESULT NIL >(AND (NUMBERP PI) (SETF RESULT 'SET-IN-SECONDAND)) SET-IN-SECOND-AND >RESULT SET-IN-SECOND-AND .technocomsolutions.AND >(setf result NIL pi 3.14) 3.com Combining Predicates .You are using demo version Please purchase full version from www.

none of the remaining is evaluated. • The arguments are evaluated from left to right. the value returned by OR is NIL.OR • OR returns NIL if all of its arguments evaluates to NIL.You are using demo version Please purchase full version from www. if any evaluates to non-NIL.technocomsolutions. . • It takes any number of arguments. and the value returned is that non-NIL value.com Combining Predicates . • If all arguments evaluates to NIL.

com Combining Predicates .technocomsolutions.You are using demo version Please purchase full version from www.OR >(setf pets '(dog cat)) (DOG CAT) >(or (member 'dingo pets) (member 'tiger pets)) NIL >(or (member 'dog pets) (member 'cat pets)) (DOG CAT) .

OR >(setf result NIL pi 3.You are using demo version Please purchase full version from www.technocomsolutions.14) 3.com Combining Predicates .14 >(OR (NUMBERP PI) (SETF RESULT 'SET-IN-FIRSTOR)) T >RESULT NIL >(OR (LISTP PI) (SETF RESULT 'SET-IN-SECOND-OR)) SET-IN-SECOND-OR >RESULT SET-IN-SECOND-OR .

NOT • NOT just turns non-NIL to NIL and NIL to T • Example >(not 'dog) NIL >(setf pets '(dog cat)) (DOG CAT) >(not (member 'dog pets)) NIL >(not (member 'tiger pets)) T .com Combining Predicates .You are using demo version Please purchase full version from www.technocomsolutions.

IF (IF <test> <then form> <else form>) • IF returns the value of its <then form> when <test> evaluates to T or ANYTHING other than NIL. • Assuming TRIGGER'S value is T.com Simple Branching Primitives . otherwise.You are using demo version Please purchase full version from www.technocomsolutions. >(IF TRIGGER 'ITS-TRUE 'ITS-FALSE) ITS-TRUE • Now assume TRIGGER's value is NIL: >(IF TRIGGER 'ITS-TRUE 'ITS-FALSE) ITS-FALSE . IF returns the value of its <else form>.

NIL will be returned.com Simple Branching Primitives .You are using demo version Please purchase full version from www.technocomsolutions. .IF >(setf day-or-date 'monday) MONDAY >(if (symbolp day-or-date) 'day 'date) DAY >(setf day-or-date 9) 9 >(if (symbolp day-or-date) 'day 'date) DATE • If there's no <else-form> and if <test> evaluates to NIL.

WHEN (WHEN <test> <then form>) • WHEN returns the value of <then form> when <test> evaluates to ANYTHING other than NIL. • Example >(WHEN T 'ITS-TRUE) ITS-TRUE • When WHEN's first argument evaluates to NIL.You are using demo version Simple Branching Primitives . WHEN returns nil: >(WHEN NIL 'ITS-TRUE) NIL Please purchase full version from www.technocomsolutions.com .

You are using demo version Simple Branching Primitives .technocomsolutions.com .WHEN >(setf high 98 temperature 102) 102 >(when (> temperature high) (setf high temperature)) 102 >high 102 Please purchase full version from www.

technocomsolutions.com .UNLESS (UNLESS <test> <else form>) • UNLESS returns the value of <else form> when <test> evaluates to NIL. • Example >(UNLESS NIL 'ITS-FALSE) ITS-FALSE • When UNLESS's first argument evaluates to non-NIL.You are using demo version Simple Branching Primitives . UNLESS returns NIL: >(UNLESS T 'ITS-FALSE) NIL Please purchase full version from www.

technocomsolutions.UNLESS >(setf high 98 temperature 102) 102 >(unless (< temperature high) (setf high temperature)) 102 >high 102 Please purchase full version from www.You are using demo version Simple Branching Primitives .com .

.)) Please purchase full version from www. ..You are using demo version General Branching Primitives .....technocomsolutions..COND (COND (<test 1> <consequent 1-1> <consequent 1-2> ..com .) .) (<test 2) <consequent 2-1> <consequent 2-2> . (<test m> <consequent m-1> <consequent m-2> ...

the value returned by COND is also NIL. • If all test forms are NIL.com .You are using demo version General Branching Primitives .COND • The symbol COND is followed by clauses. Please purchase full version from www. • The value returned by COND is the value of the last consequent form in the triggered clause. until a test form evaluates to non-NIL. This clause is "triggered" and its consequent forms are evaluated.technocomsolutions. • COND moves through the clauses. Each clause contains a test and zero or more forms called consequent. evaluating the test forms.

com .technocomsolutions.You are using demo version General Branching Primitives .COND >(cond ((= N 0) (setf answer '(value is zero))) ((> N 1) (setf answer '(value is positive))) (T (setf answer '(value is negative)))) Please purchase full version from www.

technocomsolutions.. (<key m> <consequent m-1> <consequent m-2) .. ...com ....) (<key 2> <consequent 2-1> <consequent 2-2> .You are using demo version General Branching Primitives ...)) Please purchase full version from www..CASE (CASE <key form> (<key 1> <consequent 1-1> <consequent 1-2> .) .

Please purchase full version from www. the value returned by CASE is NIL.You are using demo version General Branching Primitives .technocomsolutions. • If no matching occurs.com .CASE • CASE checks the <key form> against the <key> in each clause using "EQL" until a matching is found. • The value returned by CASE is the value of the last consequent form in the triggered clause. The corresponding clause is then triggered and all its consequent are evaluated.

the final clause is used when none of the others are triggered.You are using demo version General Branching Primitives .CASE >(setf thing 'point r 1) 1 >(case thing (circle (* pi r)) (sphere (* 4 pi r r) (otherwise 0)) NIL • The last clause in the above example is called a Catchall clause.com . Please purchase full version from www. • With a Catch-all clause.technocomsolutions.

You are using demo version General Branching Primitives .com .566 Please purchase full version from www. not an atom.technocomsolutions.CASE • If the <key> in a clause is a list. CASE checks the <key form> against the <key> list using MEMBER • Example >(setf thing 'ball r 1) 1 >(case thing ((circle wheel) (* pi r r)) ((sphere ball) (* 4 pi r r)) (otherwise 0)) 12.

• DEFUN DEfine FUNction (<parameters>) Please purchase full version from www.com (defun <function name> <forms>) • The DEFUN function establishes a function definition as its side-effect.You are using demo version Procedure Definition and Binding .technocomsolutions. . • The value returned by DEFUN is the function name.DEFUN • LISP encourages you to create small. easily debugged procedures.

Procedure's name is BOTH-ENDS. .DEFUN >(DEFUN BOTH-ENDS (L) ) BOTH-ENDS (A E) >(BOTH-ENDS '(START L M N FINISH)) (START FINISH) .End the DEFUN primitive . .com (CONS (FIRST L) (LAST L)) .LISP returns the function name Please purchase full version from www. >(BOTH-ENDS '(A B C D E)) .technocomsolutions.The form.You are using demo version Procedure Definition and Binding .The parameter is L.

the value returned by that function is the value of the last form in its body.technocomsolutions.last form Please purchase full version from www.DEFUN • When calling a function. >(defun cons-tail (tail alist) . parameters (setf count (+ count 1)) (append alist (list tail))) CONS-TAIL >(cons-tail 'pear '(apple orange)) (APPLE ORANGE PEAR) .function name.You are using demo version Procedure Definition and Binding .first form .com .

You are using demo version Procedure Definition and Binding .DEFUN • PARAMETER VARIABLES bindings are established when a function is entered. • Example: >(setf L '(a b c)) (A B C) >(defun both-ends (L) (cons (first L)(last L))) BOTH-ENDS >(both-ends '(d e f)) (D F) >L (A B C) Please purchase full version from www.com .technocomsolutions. They are isolated from other variable bindings outside the function.

DEFUN • NON-PARAMETER variables are not isolated from variables outside the function.You are using demo version Procedure Definition and Binding . • Example: >(setf count 0) 0 >(defun cons-tail (tail alist) (setf count (+ count 1)) (append alist (list tail))) CONS-TAIL >(cons-tail 'a '(b c)) (B C A) >count 1 Please purchase full version from www.com .technocomsolutions.

You are using demo version Please purchase full version from www.Using DO +--- +---Iteration----| ---Iteration----| +---Using MAPCAR ---Using . +--.com Repetition • Many LISP procedures work by repeating a particular action over and over until a certain condition is met.technocomsolutions.Recursion To repeat -----| -----| +--.

and combining the results of working on those pieces. Such procedures are said to be RECURSIVE.com Repeating by Recursion (DEFUN COUNT-ELEMENTS (L) (IF (ENDP L) 0 (+ 1 (COUNT-ELEMENTS (REST L))) ) ) • The definition of COUNT-ELEMENTS involves a form using COUNT-ELEMENTS itself. . working on its pieces.technocomsolutions. • Many recursive procedures solve problems by breaking up a list.You are using demo version Please purchase full version from www.

– All elements in a list have been worked on.technocomsolutions. .com Repeating by Iteration • You will often want to do a computation over and over until one of the two following criteria is satisfied: – A test has been satisfied.You are using demo version Please purchase full version from www.

technocomsolutions. . the <count parameter>'s binding is eliminated and the <result form> is evaluated as the return value of DOTIMES.com Repeating by Iteration . • The <count parameter> is then assigned from 0 to n-1. producing a number of n. one after another. the <upper-bound form> is evaluated.DOTIMES (dotimes (<count parameter> <upper-bound form> <result form>) <body>) • When DOTIMES is entered. • On exit.You are using demo version Please purchase full version from www. the body is executed once. • For each value.

com >(setf result 1) 1 >(dotimes (count 5 result) (setf result (* (+ 1 count) result))) 120 .You are using demo version Please purchase full version from www.technocomsolutions.

DOLIST (dolist (<element parameter> <list form> <result form>) <body>) • When DOLIST is entered. the <list form> is evaluated. • The elements in the list are then assigned.com Repeating by Iteration . • For each value.You are using demo version Please purchase full version from www. one after another. • On exit. the body is executed once. the element parameter's binding is eliminated and the <result form> is evaluated as the return value of DOLIST.technocomsolutions. . to the element parameter. producing a list of elements.

technocomsolutions.com Repeating by Iteration . • The <expression> is evaluated as the return value of the terminated DOTIMES and DOLIST form.DOLIST >(setf foo '(a b (c d)) bar '()) NIL >(DOLIST (ele foo bar) (SETF bar (CONS ele bar)))) ((C D) B A) • Whenever a (RETURN <expression>) is encountered in DOTIMES or DOLIST.You are using demo version Please purchase full version from www. computation will be terminated immediately. .

DO • DO expressions have the following parts: – A list of parameter specifications.You are using demo version Please purchase full version from www. sets. if any> <value form>) – A body that consists of DO's subforms.technocomsolutions. and resets one of the DO form's parameters: (<parameter> <initial value> <reset form>) – A test and return clause that determines when to stop the iteration and specifies the DO form's value once stopped: (<trigger> <side effect forms. each of which creates. which are evaluated over and over until the DO is stopped: <body form> .com Repeating by Iteration .

You are using demo version Please purchase full version from www.. .com Repeating by Iteration ..technocomsolutions.DO • The syntax of DO: (DO ((<parameter 1> <initial value 1> <update form 1>) (<parameter 2> <initial value 2> <update form 2>) (<parameter n> <initial value n> <update form n>)) (<test form> <result form>) <body form>) .

You are using demo version Please purchase full version from www.DO >(DO ((L '(THIS IS A LIST) (REST L)) (RESULT NIL)) ((NULL L) RESULT) (SETF RESULT (CONS (FIRST L) RESULT))) (LIST A IS THIS) >(defun do-exp (m n) (do ((result 1) (exponent n (.com Repeating by Iteration .exponent 1))) ((zerop exponent) result) (setf result (* m result)))) .technocomsolutions.

<expresion> is evaluated as the return value of the terminated DO. .e. all initial forms are evaluated before bindings and all update forms are evaluated before assignments. i.com Repeating by Iteration . DO is terminated immediately.technocomsolutions. • All initializations and updates are done in parallel.You are using demo version Please purchase full version from www.DO • Whenever (RETURN <expression>) is encountered.

You are using demo version Please purchase full version from www. • Again the <expression> is evaluated as the return value of the terminated LOOP. .LOOP (loop <body>) • The body is evaluated over and over until a (RETURN <expression>) is encountered.technocomsolutions.com Repeating by Iteration .

The s-expression is then returned as the value of read and processing continues.You are using demo version Please purchase full version from www.g. When read appears in a procedure.technocomsolutions.com Input-Output • – – read read takes no arguments. e. >(+ 5 (read)) 6 11 . processing halts until a single s-expression is entered from the keyboard.

and then returns the argument.g. e. – This makes it possible to print something and also pass the same thing on to another function as an argument. – When print is used to print an expression. >(print ‘(a b c)) (A B C) (A B C) >(print “hello there”) “hello there” “hello there” .technocomsolutions. it argument is preceded by the carriage-return and line-feed characters and is preceded by a space.You are using demo version Please purchase full version from www.com Input-Output • print – Takes one argument. – It prints the argument as it is received.

>((prin1 ‘(hello))(prin1 ‘(hello))) (HELLO)(HELLO) .com Input-Output • prin1 – e.You are using demo version Please purchase full version from www.g.technocomsolutions. • princ – e. >(princ “hello there”) hello there “hello there” Same as print except that the new-line characters and space are not provided. It is the same as prin1 except it does not print the unwanted quotation marks.g.

14159 radius radius))) CIRCLE-AREA >(circle-area) Please enter the radius: 4 The area of the circle is: 50. – It introduces a new-line (carriage return and line feed) wherever it appears and then returns nil.com Input-Output • terpri – Takes no arguments. >(defun circle-area() (terpri) (princ “Please enter the radius:”) (setq radius (read)) (princ “The area of the circle is:”) (princ (* 3. e.g.You are using demo version Please purchase full version from www.2656 .technocomsolutions.

• Directives appear in the string in the same order the arguments are to be printed. . • If destination is t the default output is monitor.com Input-Output • format (format <destination> <string> arg1 arg2…). but intermixed with format directives which specify how each argument is to be represented.You are using demo version Please purchase full version from www. • String is the desired output string.technocomsolutions. • Each directive is preceded with a tilde character (~) to identify it as a directive. • Destination specifies where the output is to be directed. like to the monitor or some other external file.

com Input-Output • – – – – – – The most common directives below: ~A The argument is printed as though princ were used. .technocomsolutions.You are using demo version Please purchase full version from www. ~C The argument is printed as character output. ~F The argument which must be a floating-point number is printed as a decimal floating-point number. ~D The argument which must be an integer is printed as a decimal number. % A new-line is printed. ~S The argument is printed as though prin1 were used.

technocomsolutions. e.You are using demo version Please purchase full version from www.0 and 9. ~5D specifies an integer field of width 5. >(format t “Circle radius=~2F~%Circle area=~3F” x y) Circle radius=3. e.g.42 respectively.42 • x and y have been bound to floating-point numbers 3.g.0 Circle area=9. .com Input-Output • The field widths for appropriate argument values are specified with an integer immediately following the tilde symbol.

working on the second element.technocomsolutions. (X Y Z).MAPCAR (MAPCAR #'<procedure-name> <list-of-things-to-work-on>) • MAPCAR takes two arguments: a procedure name and a list of things to work on. • The result is the list of values you would have if you worked on each element in the given list with the given procedure. • Example: >(MAPCAR #'FIRST '((A B C) (X Y Z))) (A X) • FIRST's result. • FIRST's result. working on the first element. (A B C). made into a list.You are using demo version Please purchase full version from www.com Transformation Primitive . is (A X). • All the results of FIRST. is X. is A. .

>(MAPCAR #'list '(a b c) '(1 2) '(x y z)) ((A 1 X) (B 2 Y)) .You are using demo version Please purchase full version from www. >(MAPCAR #'= '(1 2 3) '(3 2 1)) (NIL T NIL) • The transformation procedure is applied to the FIRST element of each list. there must be a corresponding number of lists. • For example.com Transformation Primitive .technocomsolutions.MAPCAR • If the transformation procedure requires more than 1 parameter. then the SECOND element of each list. and so on until no more elements remain in one of the lists.

You are using demo version Please purchase full version from www.technocomsolutions. • REMOVE-IF-NOT eliminates all elements that do not satisfy the filtering predicate. REMOVE-IF-NOT (remove-if #'<filtering-procedure-name> <list-of-elements-to-be-filtered>) (remove-if-not #'<filtering-procedure-name> <list-of-elements-to-be-filtered>) • REMOVE-IF eliminates all elements that satisfy the filtering predicate.com Filtering Primitive – REMOVE-IF. • Example: >(REMOVE-IF #'evenp '(1 2 3 4 5)) (1 3 5) >(REMOVE-IF-NOT #'evenp '(1 2 3 4 5)) (2 4) .

technocomsolutions.You are using demo version Please purchase full version from www. >(count-if #'evenp '(1 2 3 4 5)) 2 .com Counting Primitive . • For example.COUNT-IF (count-if #'<filtering-procedure> <list-of-elements-to-be-counted>) • COUNT-IF provides a way to count the number of elements in a list which satisfy a given condition.

technocomsolutions.FIND-IF (find-if #'<test-procedure> <list-of-elements-to-be-tested>) • FIND-IF finds the first element in the list which satisfy the testing predicate.com Finding Primitive . • For example. >(find-if #'evenp '(1 2 3 4 5 6)) 2 .You are using demo version Please purchase full version from www.

technocomsolutions.com Property List • A symbol may have property values: symbol ====== PATRICK parent property =============== (ROBERT DOROTHY) children property spouse property ================= =============== (SARAH) (CANDY) .You are using demo version Please purchase full version from www.

You are using demo version Please purchase full version from www.because no such property exists ..technocomsolutions.com Retrieving a property value (GET <symbol> <property name>) • Example: >(get 'patrick 'parent) (ROBERT DOROTHY) >(get 'patrick 'grandparent) NIL .

technocomsolutions.com Storing a property value (SETF (GET <symbol> <property name>) <property value>) • Example: >(setf (get 'patrick 'parent) '(albert dora)) (ALBERT DORA) >(get 'patrick 'parent) (ALBERT DORA) .You are using demo version Please purchase full version from www.

technocomsolutions. unbound variable >(setf albert 'patrick) PATRICK >(setf albert patrick) ERROR . only its properties have values.You are using demo version Please purchase full version from www.com Removing a property value (REMPROP <symbol> <property name>) • Example: >(remprop 'patrick 'spouse) T >(get 'patrick 'spouse) NIL • Note: If a symbol is a property list. The symbol itself does not have any value: >patrick ERROR ..

Sign up to vote on this title
UsefulNot useful