21
66 2210 - Programming in Lisp; Instr uctor: Alok Mehta 1 66-2210-01 Programming in Lisp Recursion, Data Abstraction, Mapping, Iteration

66 2210 - Programming in Lisp; Instructor: Alok Mehta1 66-2210-01 Programming in Lisp Recursion, Data Abstraction, Mapping, Iteration

  • View
    231

  • Download
    1

Embed Size (px)

Citation preview

66 2210 - Programming in Lisp; Instructor: Alok Mehta

1

66-2210-01 Programming in Lisp

Recursion, Data Abstraction, Mapping, Iteration

66 2210 - Programming in Lisp; Instructor: Alok Mehta 2

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 3

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 4

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 5

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

NiN

i

*...*3*2*11

66 436 - Data Structures (Mehta) 6

Recursively Calculating Factorial Mathematical Definition of Factorial

C/C++ Implementationlong 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)))))

XX

X X X!

, ;

*( )!,

1 1

1 1

66 2210 - Programming in Lisp; Instructor: Alok Mehta 7

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 = 24End (recursive-factorial 4), returns 24

66 436 - Data Structures (Mehta) 8

Fibonacci Numbers Mathematical Definition of Fibonacci Numbers

SequenceX 0 1 2 3 4 5 6 7 8Fib(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))))))

Fib X

X

X

Fib X Fib X X

( )

,

,

( ) ( ),

0 0

1 1

1 2 1

66 2210 - Programming in Lisp; Instructor: Alok Mehta 9

Fib(6) Function calls

F ib (1 )

F ib (2 ) F ib (1 )

F ib (3 )

F ib (1 )

F ib (2 )

F ib (4 )

F ib (1 )

F ib (2 ) F ib (1 )

F ib (3 )

F ib (5 )

F ib (1 )

F ib (2 ) F ib (1 )

F ib (3 )

F ib (1 )

F ib (2 )

F ib (4 )

F ib (6 )

66 2210 - Programming in Lisp; Instructor: Alok Mehta 10

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 11

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 12

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 13

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 436 - Data Structures (Mehta) 14

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 2210 - Programming in Lisp; Instructor: Alok Mehta 15

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 16

&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 17

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 18

&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 19

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 20

&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 21

&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)))