Transcript Lecture 2

LISP primitives on sequences
FIRST (or CAR) and REST (or CDR) take lists apart.
Consider the list (First day of the semester).
* (first '(First day of the semester))
FIRST
* (rest '(First day of the semester))
(DAY OF THE SEMESTER)
(A B C)
First
A
Rest
(B C)
Examples
*
(first ( ))
NIL
* (rest ( ))
NIL
* (first '((a b) (c d))
(A B)
* (rest '((a b) (c d))
((C D))
* (car '(a . b))
A
* (cdr '(a . b))
B
The QUOTE mark
'
stops evaluation
* (first (rest '(a b c))) ;second returns
B
;the 2nd element
* (first '(rest (a b c))) ;third returns
REST
;the 3rd element,...
* (first (rest (a b c))) ;tenth returns
?
;the 10th element
>>> Error:Undefined function: A
while evaluating: (A B C)
(#<COMPILED-FUNCTION 3:E196> ...)
Debugger 1>
Examples
* (first (first (rest '(rest ((a b)(c d)(e f))))))
(A B)
* (first '(((a b) (c d) (e f))))
((A B) (C D) (E F))
Given (apple (orange)((pear))(((kiwi))))), write a sequence of FIRST and
REST which returns PEAR.
* (first (first (first (rest (rest '(apple (orange) ((pear)) (((kiwi)))))))))))))
PEAR
* (rest '(apple (orange) ((pear)) (((kiwi)))))))))
((ORANGE) ((PEAR)) (((KIWI))))
* (rest '((orange) ((pear)) (((kiwi)))))
(((PEAR)) (((KIWI))))
* (first (first (first '(((pear)) (((kiwi)))))))
PEAR
The SETF / SETQ primitives




The process of reserving a place in memory to store a value is called
binding.
The process of storing a value for a symbol is called assignment.
The process of recovering a value from memory is called evaluation.
SETF / SETQ assign values to symbols
* (setf ab-list '(a b))
(a b)
* ab-list
(a b)
* (setf ab-list '(a b) cd-list '(c d))
(c d) ; accepts multiple symbol-value pairs,
; but returns only the last assignment
SETF alters the contents of the cons cell storing the
symbol.
* (setf fact1 '(CS462 is a fun course))
(CS462 IS A FUN COURSE)
* fact1
(CS462 IS A FUN COURSE)
fact1
CS462
is
a
fun
course
* (first fact1)
CS462
* fact1
(CS462 IS A FUN COURSE)
* (setf (first fact1) 'CS463)
fact1
CS463
is
a
* fact1
(CS463 IS A FUN COURSE)
fun
course
CONS, APPEND and LIST primitives construct lists
* (cons 'a '(b c))
(A B C)
FIRST
A
CONS
(A B C)
REST
* (append '(a b c) '(x y z))
(A B C X Y Z)
* (list '(a b c) '(x y z))
((A B C) (X Y Z))
(B C)
;combines elements
;combines lists
(A B C)
* (append 'list1 'list2)
ERROR
; does not accept atoms as arguments
* (list 'list1 ' (x y z))
(LIST1 (X Y Z))
; arguments can be both atoms and lists
CONS, APPEND and LIST do not alter symbol values.
REST, NTHCDR, BUTLAST and LAST shorten
lists
* (rest '(a b c d))
(B C D)
; list without its first element
* (nthcdr 2 '(a b c d))
(C D)
; list without ‘n’ first elements.
* (nthcdr 4 '(a b c d))
NIL
* (butlast '(a b c d) 2)
(A B)
; list without ‘n’ last elements.
* (butlast '(a b c d))
(A B C)
; list without its last element.
* (last '(a b c d))
(D)
; list of just the last element.
* (last '((a b) (c d) (e f)))
((E F))
More examples




Add D at the end of the list (A B C)
* (append '(a b c) (list 'd))
(A B C D)
Add D at the beginning of the list (A B C)
* (cons 'd '(a b c))
(D A B C)
Add D as a second element in the list (A B C)
* (append (list (first '(a b c))) (list 'd) (nthcdr 1 '(a b c)))
(A D B C)
Create a list of D and the last element of (A B C)
* (setf new-list (list 'd (first (last '(a b c)))) )
(D C)
* new-list
(D C)
LENGTH counts the number of top-level elements,
REVERSE reverses the order of top-level elements
* (length '(a b ((c d) (e f))))
3
* (length (append '(a b ((c d) (e f))) '(x y z)))
6
* (reverse '(a b ((c d) (e f))))
(((C D) (E F)) B A)
* (reverse (append '(a b ((c d) (e f))) '(x y z)))
(Z Y X ((C D) (E F)) B A)
User-defined procedures: the DEFUN primitive
Build a list (a d) out of the list (a b c d).
I way: Use the CONS primitive
* (cons (first '(a b c d)) (last '(a b c d)))
(A D)
II way: Create a new procedure both-ends
* (both-ends '(a b c d))
(A D)
* (defun both-ends (whole-list)
(cons (first whole-list)
(last whole-list)))
BOTH-ENDS
General form of the DEFUN primitive
(defun <procedure name> (<parameter list>)
<form 1> <form 2> …
<form n>)
DEFUN does not evaluate its arguments, it only
establishes the procedure definition.
Example (cont.)
* (setf whole-list '(a b c d))
(A B C D)
* whole-list
(A B C D)
* (both-ends whole-list)
(A D)
* whole-list
(A B C D) ; the value was not affected by both-ends which
used the same atom as argument.
LISP distinguishes between local (lexical) and
special (global) variables


Parameters in procedures are local variables. They are
bound to argument value only inside the procedure.
Values of global variables are set with the SETF primitive.
Example:
* (defun both-ends-global ( )
(setf whole-list (cons (first whole-list)(last whole-list))))
BOTH-ENDS-GLOBAL
* whole-list
(A B C D)
* (both-ends-global)
(A D)
* whole-list
(A D)
Procedures may have any number of parameters
* (defun both-ends-two-parameters (x y)
(cons (first x) (last y)))
BOTH-ENDS-TWO-PARAMETERS
* (setf x '(a b) y '(c d))
(C D)
* (both-ends-two-parameters x y)
(A D)
Procedures may produce side effects
* (defun both-end-with-side-effect (x y)
(setf side-effect-1 '(This is a side effect))
(setf side-effect-2 '(Another side effect))
(cons (first x) (last y)))
BOTH-END-WITH-SIDE-EFFECT
* side-effect-1
Unbound symbol: SIDE-EFFECT-1
* side-effect-2
Unbound symbol: SIDE-EFFECT-2
* (both-end-with-side-effect x y)
(A D)
* side-effect-1
(THIS IS A SIDE EFFECT)
* side-effect-2
(ANOTHER SIDE EFFECT)