210 likes | 371 Vues
Explore Lisp programming concepts such as recursion, data abstraction, and iteration with examples and error handling techniques taught by instructor Alok Mehta. Learn about factorial and Fibonacci calculations, tail recursion, and more.
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