Presentation is loading. Please wait.

Presentation is loading. Please wait.

>(setf oldlist ) Constructing a list We know how to make a list in lisp; we simply write it: ‘4321( ) What if we want a new list with that list as a part?

Similar presentations


Presentation on theme: ">(setf oldlist ) Constructing a list We know how to make a list in lisp; we simply write it: ‘4321( ) What if we want a new list with that list as a part?"— Presentation transcript:

1 >(setf oldlist ) Constructing a list We know how to make a list in lisp; we simply write it: ‘4321( ) What if we want a new list with that list as a part? For example, what if we want ‘(5 4 3 2 1) ? (4 3 2 1) >(setf newlist )‘4321( ) We could either type the whole thing: 5 (5 4 3 2 1) Or we could construct the newlist from two parts: the new element and the oldlist (5 4 3 2 1) >(setf newlist )(cons )5oldlist

2 The rule of cons Cons takes two arguments: an element and a list >(setf newlist (cons 5 oldlist)) and evaluates to a new list with the element as its first part and the list argument as the rest of the new list (5 4 3 2 1) The functions first and rest are like the reverse of cons >(first newlist) 5 First returns the element given to cons >(rest newlist) (4 3 2 1) Rest returns the list given to cons

3 Using cons to build up an answer Countdown will be a recursive function. It will use cons to combine the smaller list returned by the recursive call with the “left-behind” element to produce a new, bigger list. All the functions we’ve seen so far return a single element as an answer; e.g. (factorial N) returns a number Sometimes we want to return a more complex answer from a function: a list of elements. A simple example: (countdown N) returns the list of numbers from N down to 1. > (countdown 7) (7 6 5 4 3 2 1)

4 (defun countdown(N) ) (cond ( ) ) ( t )(cons N ) (= N 0) 1) Check if the argument is so simple the function can give an answer straight away. If so, give the answer & stop Have the function call itself as a helper to get an answer for that smaller argument Compute a smaller version of the argument Combine that answer with the left-behind part of the argument, to get the overall answer to the original question Writing the countdown function 2) If the argument is too big to give an immediate answer (countdown ) (- N 1) ‘() Reminder: parts of a recursive function

5 1. Make a copy of the function; replace N by 2 (defun countdown( 2 ) (cond( (= 2 0) ‘() ) ( t (cons 2 (countdown (- 2 1))) ) ) ) 3. (= 0 0) is true (t); just return ‘() as the answer ( t ‘()) 1. Make a copy of the function and replace N by 0 (defun countdown(0) (cond ( (= 0 0) ‘() ) ( t (cons 0 (countdown (- 0 1))) ) ) ) 3a. Eval (- 1 1) (cons 1 (countdown (- 1 1))) 3b. Eval (countdown 0 ) (cons 1 (countdown 0) ) 1. Make a copy of the function and replace N by 1 (defun countdown ( 1 ) (cond ( (= 1 0) ‘() ) ( t (cons 1 (countdown (- 1 1))) ) ) ) 2. Evaluate the body of the function (cond ( (= 1 0) ‘() ) ( t (cons 1 (countdown (- 1 1) ) )) 3. (= 1 0) is false (nil); evaluate (cons 1 (countdown (- 1 1))) 3.(= 2 0) is false (nil); go to next line and eval (cons 2 (countdown (- 2 1))) 2. Evaluate the body of the function (cond ( (= 2 0) ‘() ) ( t (cons 2 (countdown (- 2 1))) ) ) ) 3a. Eval (- 2 1) (cons 2 (countdown (- 2 1) )) Tracing the countdown function 3b. Eval (countdown 1) (cons 2 (countdown 1) ) 3c. Construct the new list (cons 2 ‘( 1 ) ) 3c. Construct the new list (cons 1 ‘() ) 2. Evaluate the body of the function (cond ( (= 0 0 ) ‘() ) ( t (cons 0 (countdown (- 0 1)))) ) ) (defun countdown(N) (cond ( (= N 0) ‘() ) ( t (cons N (countdown (- N 1))) ) ) ) > (countdown 2) ‘( 1 ) ‘() 1 0 ‘( 1 ) ‘( 2 1) (2 1)

6 Things to note about using cons in recursive functions Cons takes as its arguments and element and a list; The recursive function should return a list to allow cons to build on that list. Therefore, the value returned in the stopping condition should be a list (usually its an empty list). Cons is used to add an element to the answer returned by a recursive call. In countdown, that element is simply the current N. The element can be more complex; it could be the result of some processing on the current item.

7 (defun negatives(L) ) (cond ( ) ) ( t )(negatives ) ( ) Go through the list recursively one element at a time On each loop, check if the first element of the list is < 0 stop when? Stopping condition(null L) Function definition recursive condition2 ‘() (rest L) If current element < 0, cons that element to recursive answer (cons ) Recursive condition1(< (first L) 0) When we get to the end of the list If it is not < 0, simply pass back the recursive answer (negatives )(first A)(rest L) Use cons to take a list & return a list A function (negatives L) that takes a list of numbers L and returns a list containing only negative numbers from L.

8 general pattern for selecting some elements of a list This negatives example illustrates a general pattern: If you want a function which selects some elements from a list and drops others, you need a recursive function with two recursive conditions. (defun negatives(L) (cond ( (null L) ‘() ) ( (< (first L) 0 ) (cons (first L) (negatives (rest L))) ) ( t (negatives (rest L)) ) )) One recursive condition conses the current first element to the answer that’s being built up, because it matches the criterion The other recursive condition simply returns the answer built up for the rest of the list, “ignoring” the current first element


Download ppt ">(setf oldlist ) Constructing a list We know how to make a list in lisp; we simply write it: ‘4321( ) What if we want a new list with that list as a part?"

Similar presentations


Ads by Google