Title: Reminder: if and cond
1Reminder if and cond
If and cond are both conditional functions they
both return different values depending on the
result of logical tests
(defun abs(X) (if (gt X 0) X ( X 1)
) )
If ( function_name test result_if_true
result_if_false )
(defun abs(X) (cond ( (gt X 0) X
) ( t
( X 1) ) ) )
cond ( function_name testresult_pair
testresult_pair )
( test result_if_true )
( test result_if_true )
An if call is a simple list with 4 elements. A
cond call is a list starting with cond, and
followed by a series of internal lists. Each
internal list contains 2 elements a test and a
result returned if that test it true
2Using t in cond
(defun abs(X) (cond ( (gt X 0) X
) ( t
( X 1) ) ) )
A cond call starts with the function name cond
followed by a series of lists. Each list is a
pair containing two elements a test, and a
result.
Cond goes through these lists in order, one at a
time. For each list, it tests whether the first
element in the list is true. If the first
element is true, cond returns the second element
in the list and does not go on to the remaining
lists.
Often the last list in a cond call has a t as
its first element (where the test would normally
be). t is always true. If cond gets through
all the other lists as far as the last list, the
t means it will always return the second element
of this list.
3And, Or and Not
You can use And, Or, and Not in your logical
tests for if and cond. These functions combine
tests, and return t or nil
(if (and ( (first L) 1) ( (first (rest L)) 2)
( (third L) 3) )
close bracket for and
As many tests as you like, each in its own
brackets
Open bracket for and
(if (or ( (first L) 1) ( (first L) 2) (
(first L) 3) )
close bracket for or
As many tests as you like, each in its own
brackets
Open bracket for or
unlike the other two, not can only take a single
test as its argument.
(if (not ( (first L) 1) )
4Recursion count the number of elements in a list
This is going to be a loop where we
- consider each element of a list (count that
element)
- when weve counted an element, go on to rest of
the list
- stop when we get to the end of the list
Function definition
(defun len(L) )
Stopping condition
(null L)
(cond ( ) )
0
( 1 )
( t )
(len )
recursive condition
(rest L)
5How does recursion with lists work?
(defun len(L) (cond ( (null L) 0
) ( t ( 1 (len
(rest L))) ) ) )
gt (len (a b))
2
2
1. Make a copy of the function replace L by (a
b) (defun len( (a b) ) (cond( (null (a b))
0 ) ( t
( 1 (len (rest (a b)))) )
) )
2. Evaluate the body of the function (cond (
(null (a b)) 0 )
( t ( 1 (len (rest (a b))) ) ) )
3a. Eval (rest (a b)) ( 1(len (rest (a b))
))
3b. Eval (len (a)) ( 1 (len (a)) )
3c. Add 1 ( 1 1 )
- (null (a b)) is false (nil) go to next line and
eval ( 1 (len (rest (a b)))) -
-
1
(a)
2
1. Make a copy of the function and replace L by
(a) (defun len ( (a) ) (cond ( (null (a))
0 ) ( t
( 1 (len (rest (a)))) ) ) )
2. Evaluate the body of the function (cond (
(null (a)) 0 )
( t ( 1 (len (rest (a)))) ) ))
3. (null (a) is false (nil) evaluate ( 1 (len
(rest (a))))
3a. Eval (rest (a)) ( 1 (len (rest (a)) ))
3b. Eval (len () ) ( 1 (len () ) )
3c. Add 1 ( 1 0 )
0
()
1
2. Evaluate the body of the function (cond (
(null () ) 0 )
( t ( 1 (len (rest ())) ) )
3. (null ()) is true (t) just return 0 as the
answer ( t 0)
1. Make a copy of the function and replace L by
() (defun len( () ) (cond ( (null () )
0 ) ( t ( 1 (len
(rest ()))) ) )
6Sum the elements of a list
This is going to be a loop where we
- Add the first element of the list
- Apply the function to sum up the rest of the list
- stop when we get to the end of the list
Function definition
(defun sum(L) )
(cond (
) )
Stopping condition
(null L)
0
( t
)
( )
(sum )
recursive condition
(rest L)
(first l)
7Design pattern for simple recursive fns
(defun MyFn(arg1 arg2.) )
( stopping-condition1 arg??)
ans??
(cond )
(
)
( stopping-condition2 arg??)
ans??
(
)
( recursive-test1 args??)
(
)
(MyFn smaller-args??)
(combine arg??
)
(
)
( recursive-test2 args??)
In recursion, we combine one part of the
arguments (in some way)
(combine arg??
)
(MyFn smaller-args??)
with the result of a recursive call to the
function with a smaller (in some way) arguments
8example with two stopping conditions
(member A L) returns t if element A occurs
somewhere in list L, and returns nil or () if
not.
This is going to be a loop where we
- go through the list recursively one element at a
time
- On each loop, check if the first element of the
list is A
1) we get to the end of the list
2) we find the element A
(defun member(A L) )
Function definition
(cond (
) )
(null L)
nil
Stopping condition1
(
)
(first L)
t
Stopping condition2
(equal A )
( t
)
A
(member )
(rest l)
recursive condition
9example with two recursive conditions
(count A L) counts the number of times element A
occurs in list L, and returns that number.
Go through the list recursively one element at a
time
On each loop, check if the first element of the
list is A
- If the current element is A, add 1 to the
recursive answer
- If it is not A, simply pass back the recursive
answer
stop when?
When we get to the end of the list
(defun count(A L) )
Function definition
(cond (
) )
(null L)
0
Stopping condition
(
)
(first L)
(equal A )
Recursive condition1
( 1 )
(count )
A
(rest l)
( t
)
(count )
A
recursive condition2
(rest l)
10general pattern for recursion on lists
Each recursive call involves a shortened version
of the list (usually (rest L), but can also be
(rest (rest L)) etc.)
Each call involves some action or comparison on
the first element of the list (first L) (or
sometimes the first two etc.)
One stopping condition is always when the list is
empty. There can be other stopping conditions
too.
Next we will see how to write recursive functions
that construct lists. This will use the function
cons.