210 likes | 360 Views
66-2210-01 Programming in Lisp. Recursion, Data Abstraction, Mapping, Iteration. Example: Both-ends. Define a procedure that gives both ends of a list > (setf itinerary ’(Albany NYC Chicago Seattle Anchorage)) > (both-ends itinerary) (ALBANY ANCHORAGE) Three steps Get first element
E N D
66-2210-01 Programming in Lisp Recursion, Data Abstraction, Mapping, Iteration 66 2210 - Programming in Lisp; Instructor: Alok Mehta
Example: Both-ends • Define a procedure that gives both ends of a list • > (setf itinerary ’(Albany NYC Chicago Seattle Anchorage)) • > (both-ends itinerary) • (ALBANY ANCHORAGE) • Three steps • Get first element • > (first itinerary) • ALBANY • Get last element • > (first (last itinerary)) • ANCHORAGE • Combine the two • > (list (first itinerary) (first (last itinerary))) • Define procedure • > (defun both-ends (l) (list (first l) (first (last l)))) 66 2210 - Programming in Lisp; Instructor: Alok Mehta
Error handling • Both-ends with error handling • (defun both-ends (l) • (if (listp l) • (case (length l) • (0 NIL) • (1 (list (first l) (first l))) • (t (list (first l) (first (last l))))) • NIL)) 66 2210 - Programming in Lisp; Instructor: Alok Mehta
DoTimes • DOTIMES is Lisp’s way of doing iteration • C/C++ • for (i=0; i<n; i++) { • <body> • } • Lisp • (dotimes (i n) <body>) • First parameter is a list with three elements • counter variable (e.g. i) • number of times to iterate (e.g. n) • Counter variable (i) ranges from 0 to n-1 • Optional return value can be specified (default is NIL) • (dotimes (i n return_value) <body>) 66 2210 - Programming in Lisp; Instructor: Alok Mehta
Factorial • Definition of Factorial • C++ Implementation • int factorial (int x) { • int i,f; • f = 1; • for (i=1; i<=x; i++) f = f * i; • return f; • } • Lisp Implementation • (defun factorial (n) • (let ((f 1)) • (dotimes (i n) • (setf f (* f (+ i 1)))) • f • ) • ) • Tip: Compute factorial(100) using C/C++ and Lisp 66 2210 - Programming in Lisp; Instructor: Alok Mehta
Recursively Calculating Factorial • Mathematical Definition of Factorial • C/C++ Implementation • long Factorial (long X) { • if (X <= 1) • return 1; • else • return X * Factorial(X-1); • } • Lisp Implementation • (defun recursive-factorial (x) • (if (<= x 1) • 1 • (* x (recursive-factorial (- x 1))))) 66 436 - Data Structures (Mehta)
Recursive calls • Show recursion when calling (recursive-factorial 4) • Begin (recursive-factorial 4) • Since 4>1, evaluate 4 * (recursive-factorial 3) • Begin (recursive-factorial 3) • Since 3>1, evaluate 3 * (recursive-factorial 2) • Begin (recursive-factorial 2) • Since 2>1, evaluate 2*(recursive-factorial 1) • Begin (recursive-factorial 1) • Since 1<=1, return 1 • End (recursive-factorial 1), returns 1 • 2 * (recursive-factorial 1) = 2 * 1 = 2 • End (recursive-factorial 2), returns 2 • 3 * (recursive-factorial 2) = 3 * 2 = 6 • End (recursive-factorial 3), returns 6 • 4 * (recursive-factorial 3) = 4 * 6 = 24 • End (recursive-factorial 4), returns 24 66 2210 - Programming in Lisp; Instructor: Alok Mehta
Fibonacci Numbers • Mathematical Definition of Fibonacci Numbers • Sequence • X 0 1 2 3 4 5 6 7 8 • Fib(X) 0 1 1 2 3 5 8 13 21 • Recursive Solution • (defun fib (x) • (cond ((= x 0) 0) • ((= x 1) 1) • (t (+ (fib (- x 1)) (fib (- x 2)))))) 66 436 - Data Structures (Mehta)
Fib(6) Function calls 66 2210 - Programming in Lisp; Instructor: Alok Mehta
Recursive Definition of Length • Length • (defun mylength (l) • (if (endp l) • 0 • (+ 1 (mylength (rest l))))) • Alternate definition • (defun mylength2 (l) • (mylength2-aux l 0)) • (defun mylength2-aux (l count) • (if (endp l) • count • (mylength2-aux l (+ count 1)))) • Note • All recursive calls simply return the final value evaluated. • No additional computations 66 2210 - Programming in Lisp; Instructor: Alok Mehta
Tail Recursion • Tail Recursion • The final expression of a function is a recursive call • No additional computations are done to that expression • That is, return value is JUST the result of the recursive call • Lisp handles tail recursion efficiently • Mylength is not tail recursive • Mylength2 is tail recursive • Example: • Write a function to produce N atoms with value ‘A’. • > (produce-list-of-a 5) ; Example call • (A A A A A) 66 2210 - Programming in Lisp; Instructor: Alok Mehta
Produce-list-of-a • Using dotimes • (defun produce-list-of-a (n) • (let ((la NIL)) • (dotimes (i n la) (push 'A la)))) • Recursion, not tail recursive • (defun produce-list-of-a (n) • (if (= n 0) • nil • (cons 'A (produce-list-of-a (- n 1))))) • Recursion, with tail recursion • (defun produce-list-of-a (n) • (produce-list-of-a-aux n NIL)) • (defun produce-list-of-a-aux (n list-so-far) • (if (= n 0) • list-so-far • (produce-list-of-a-aux • (- n 1) • (cons 'A list-so-far)))) 66 2210 - Programming in Lisp; Instructor: Alok Mehta
Count-Atoms • Write function to count number of atoms in an expr • (sqrt (+ (expt x 2) (expt y 2))) • has eight atoms • (defun count-atoms (l) • (cond ((null l) 0) • ((atom l) 1) • (t (+ (count-atoms (first l)) • (count-atoms (rest l)))))) 66 2210 - Programming in Lisp; Instructor: Alok Mehta
Tower of Hanoi • Three pegs, S(start), T(temp), E(end) • N disks • Goal: Move disks from peg S to peg E • Restriction: Larger disk can’t be placed on top of smaller disk S T E 66 436 - Data Structures (Mehta)
Tower of Hanoi • Solution to Tower of Hanoi • (defun hanoi-aux (n start end temp) • (if (> n 1) (hanoi-aux (- n 1) start temp end)) • (print (list start end)) • (if (> n 1) (hanoi-aux (- n 1) temp end start))) • (defun hanoi (n) (hanoi-aux n 'S 'E 'T)) • Example Runs • > (hanoi 2) • (S T) • (S E) • (T E) • NIL > (hanoi 3) (S E) (S T) (E T) (S E) (T S) (T E) (S E) NIL 66 2210 - Programming in Lisp; Instructor: Alok Mehta
&Optional • Produce-list-of-a function(s) • (defun produce-list-of-a (n) • (produce-list-of-a-aux n NIL)) • (defun produce-list-of-a-aux (n list-so-far) • (if (= n 0) • list-so-far • (produce-list-of-a-aux • (- n 1) • (cons 'A list-so-far)))) • Redefined with optional parameters • (defun produce-list-of-a (n &optional list-so-far) • (if (= n 0) • list-so-far • (produce-list-of-a • (- n 1) • (cons 'A list-so-far)))) • Note: optional values are bound to NIL, by default 66 2210 - Programming in Lisp; Instructor: Alok Mehta
Optional Parameters (cont) • Solution to Hanoi • (defun hanoi-aux (n start end temp) • (if (> n 1) (hanoi-aux (- n 1) start temp end)) • (print (list start end)) • (if (> n 1) (hanoi-aux (- n 1) temp end start))) • (defun hanoi (n) (hanoi-aux n 'S 'E 'T)) • Revised with optional parameters • (defun hanoi (n &optional (start 'S) (end 'E) (temp 'T)) • (if (> n 1) (hanoi (- n 1) start temp end)) • (print (list start end)) • (if (> n 1) (hanoi (- n 1) temp end start))) • Note: notice the syntax for initializing optional parameters 66 2210 - Programming in Lisp; Instructor: Alok Mehta
&Rest • &Rest - Specifies a variable number of arguments • Example: Assume + only accepts 2 arguments. Define “Plus”, a function that adds an arbitrary number of arguments) • > (plus 2 3) • > (plus 2 3 4 5 8) • Solution • (defun plus (arg1 &rest other_args) • (plus-aux arg1 other_args)) • (defun plus-aux (arg1 other_args) • (if (null other_args) • arg1 • (plus-aux (+ arg1 (first other_args)) • (rest other_args)))) 66 2210 - Programming in Lisp; Instructor: Alok Mehta
Key Parameters • KEYword parameter • Useful when function has MANY parameters • Most are tied to default values • Examples • > (rotate-list '(a b c d e)) ; rotate one element right • (E A B C D) • > (rotate-list '(a b c d e) :direction 'left) • (B C D E A) • > (rotate-list '(a b c d e) :distance 2) • (D E A B C) • > (rotate-list '(a b c d e) :direction 'left :distance 2) • (C D E A B) 66 2210 - Programming in Lisp; Instructor: Alok Mehta
&Key • Use &key to define Key parameters • (defun rotate-list (l &key (direction 'right) (distance 1)) • (if (eq direction 'left) • (rotate-list-left l distance) • (rotate-list-right l distance))) • (defun rotate-list-right (l n) • (if (zerop n) • l • (rotate-list-right (append (last l) (butlast l)) • (- n 1)))) • (defun rotate-list-left (l n) • (if (zerop n) • l • (rotate-list-right (append (rest l) (list (first l))) • (- n 1)))) 66 2210 - Programming in Lisp; Instructor: Alok Mehta
&Aux • &Aux keyword is used as a shorthand for Let* • Produce-list-of-a using Let* • (defun produce-list-of-a (n) • (let* ((la NIL)) • (dotimes (i n la) (push 'A la)))) • Using &Aux • (defun produce-list-of-a (n &aux (la NIL)) • (dotimes (i n la) (push 'A la))) 66 2210 - Programming in Lisp; Instructor: Alok Mehta