Presentation is loading. Please wait.

Presentation is loading. Please wait.

CSCI 2210: Programming in Lisp

Similar presentations


Presentation on theme: "CSCI 2210: Programming in Lisp"— Presentation transcript:

1 CSCI 2210: Programming in Lisp
Procedures CSCI 2210: Programming in Lisp Procedures CSCI Programming in Lisp; Instructor: Alok Mehta CSCI Programming in Lisp; Instructor: Alok Mehta

2 Example: Our-third Function to get the third element of a list
> (third '(a b c d e)) c How can we do this without using THIRD? Want to create our own function, OUR-THIRD that mimics THIRD > (our-third '(a b c d e)) Definition of OUR-THIRD > (defun our-third (x) (first (rest (rest x)))) OUR-THIRD Many Lisp built-in functions can be written using other Lisp built-in functions See Appendix B, Lisp in Lisp. CSCI Programming in Lisp; Instructor: Alok Mehta

3 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)))) CSCI Programming in Lisp; Instructor: Alok Mehta

4 Example: Distance Write a function to find the distance between 2 points. > (defun sqr (x) (* x x)) SQR > (defun distance (x1 y1 x2 y2) (sqrt (+ (sqr (- x2 x1)) (sqr (- y2 y1))))) DISTANCE > (setf originx 0 originy 0) > (distance originx originy 2 2) 1.414 Must have correct number of arguments The value of each argument is copied to the corresponding parameter originx copied to x1 originy copied to y1 2 copied to x2 2 copied to y2 CSCI Programming in Lisp; Instructor: Alok Mehta

5 Scope Consider Value of C is copied to A
> (setf a ’ORIG-A b ’ORIG-B c ’ORIG-C) ORIG-C > (list a b c) (ORIG-A ORIG-B ORIG-C) > (defun myfun (a) (setf a ’myfun-a) (setf b ’myfun-b) (list a b)) > (myfun c) (MYFUN-A MYFUN-B) (ORIG-A MYFUN-B ORIG-C) Value of C is copied to A Parameter passing: Pass by Value (Like C/C++ default) Global variables are still accessible! Like C/C++ Global variables Lexical variable: variable declared as a parameter Special variable: variable not declared as a parameter A,B,C A CSCI Programming in Lisp; Instructor: Alok Mehta

6 Let Let = Lisp’s way of defining local variables Example
(let ( (<var1> <value1>) (<var2> <value2>) … ) <expr1> <expr2> ) Example (defun distance (x1 y1 x2 y2) (let ( (dx (- x2 x1)) (dy (- y2 y1)) ) (sqrt (+ (sqr dx) (sqr dy))) )) Let evaluates in parallel (not sequentially) Uses original values of variables in all (<var> <value>) pairs (let ( (dx (- x2 x1)) (dy (- y2 y1)) (dx_sqr (sqr dx)) (dy_sqr (sqr dy)) ) ;; Won’t work! (sqrt (+ dx_sqr dy_sqr)) ) CSCI Programming in Lisp; Instructor: Alok Mehta

7 Let vs. Let* Let - Parallel evaluation Let* - Sequential evaluation
> (setf x ’outside) OUTSIDE > (let ((x ’inside) (y x)) (list x y)) (INSIDE OUTSIDE) Let* - Sequential evaluation > (let* ((x ’inside) (y x)) (list x y)) (INSIDE INSIDE) Let* Implementation of distance (let* ( (dx (- x2 x1)) (dy (- y2 y1)) (dx_sqr (sqr dx)) (dy_sqr (sqr dy)) ) ;; OK! (sqrt (+ dx_sqr dy_sqr)) ) CSCI Programming in Lisp; Instructor: Alok Mehta

8 Exercise 1. Rewrite the distance function to use “setf” instead of “let”. Explain the difference. 2. Write the function solve-quadratic such that, given a,b,c, the function finds all values of x for which ax^2 + bx + c = 0. x1 = (-b + sqrt (b^2 - 4ac)) / 2a x2 = (-b - sqrt (b^2 - 4ac)) / 2a The function should return both values of x as a list of two elements. For example, > (solve-quadratic ) ( ) CSCI Programming in Lisp; Instructor: Alok Mehta

9 Example: Solve-quadratic
Solution to solve-quadratic (defun solve-quadratic (a b c) (let ((sqrt_clause (- (* b b) (* 4 a c))) (neg_b (- b)) (two_a (* 2 a)) ) (list (/ (+ neg_b (sqrt sqrt_clause)) two_a) (/ (- neg_b (sqrt sqrt_clause)) two_a)))) Notes - No error checking is done (- (* b b) (* 4 a c)) might result in a negative number What happens when you try to take sqrt of a negative number? What happens when the value of A is zero? Need Predicates - to determine when error conditions occur (e.g. =) Conditionals - to do something else when error occurs CSCI Programming in Lisp; Instructor: Alok Mehta

10 EQUAL does not = EQL Several predicates check equality
Slightly different semantics Can be confusing Equality predicates Equal - Are two argument values the same expression? Eql - Are two argument values the same symbol or number? Eq - Are two argument values the same symbol? = - Are two argument values the same number? General Rule of Thumb Use = when you want to compare numbers Use EQUAL otherwise CSCI Programming in Lisp; Instructor: Alok Mehta

11 Relationships Bet Equality Pred’s
F = EQL A EQ D E B C EQ vs. = = returns T if two numbers are the same, regardless of their type EQ returns T if two arguments are the same symbol Same chunk of memory Identical primitives sometimes are EQ Examples > (eq 4 4) ;; EQ:T =:T (C) > (eq (/ 1 4) 0.25) ;; EQ:NIL =:T (A) > (eq ’A ’A) ;; EQ:T =:Error (D) > (eq ) ;; EQ:NIL =:T (A) CSCI Programming in Lisp; Instructor: Alok Mehta

12 EQL vs. = EQL Arguments are EQL if they are either EQ or they are equivalent numbers of the same type Examples > (eq ) ;; EQ:NIL EQL:T =:T (B) > (eq 4 4.0) ;; EQ:NIL EQL:NIL =:T (A) EQUAL Arguments are EQUAL if they are either EQL or they are Lists whose elements are EQUAL Performs an element by element comparison of lists CSCI Programming in Lisp; Instructor: Alok Mehta

13 EQUAL vs. EQL vs. = EQUAL vs. EQL EQUAL vs. =
C EQUAL vs. EQL > (setf X ’(A (B (C)))) > (setf Y X) > (setf Z ’(A (B (C)))) X and Y are EQUAL and EQL X and Z are EQUAL but not EQL They don’t point to the SAME memory But, if you do an element by element comparison of the lists, they are equal EQUAL vs. = > (EQUAL 4 4.0) NIL > (= 4 4.0) T B A X C Y B A Z CSCI Programming in Lisp; Instructor: Alok Mehta

14 Data Type Predicates Data Type Predicates
Compare objects to determine their type atom - Is argument an atom? numberp - Is argument a number? symbolp - Is argument a symbol (a non-numeric atom)? listp - Is argument a list? Examples > (list pi ’ABC) ( ABC) > (list (atom pi) (atom ’ABC)) (T T) > (list (numberp pi) (numberp ’ABC)) (T NIL) > (list (symbolp pi) (symbolp ’ABC)) (NIL T) > (list (listp pi) (listp ’ABC) (listp ’(A B)) (NIL NIL T) CSCI Programming in Lisp; Instructor: Alok Mehta

15 Number Predicates Number predicates numberp - Is it a number?
zerop - Is it zero? Argument must be a number plusp - Is it positive? Argument must be a number minusp - Is it negative? Argument must be a number evenp - Is it even? oddp - Is it odd? > - Is the list of arguments in descending order? (e.g. (> 5 4)) < - Is the list of arguments in ascending order? CSCI Programming in Lisp; Instructor: Alok Mehta

16 If, When, Unless If When Unless
(if <test> <then-form> <else-form>) if <test> is true <then-form> is evaluated, otherwise <else-form> is evaluated. When (when <test> <then-form1> <then-form2> …) If <test> is true, then other arguments are evaluated. Unless (unless <test> <else-form1> <else-form2> …) If <test> is false, then other arguments are evaluated. CSCI Programming in Lisp; Instructor: Alok Mehta

17 Cond Cond format Semantics
(COND (<test1> <then-1-1> <then-1-2> …) (<test2> <then-2-1> <then-2-2> …) (<test3> <then-3-1> <then-3-2> …) (<testi> <then-i-1> <then-i-2> …) (<testm> <then-m-1> <then-m-2> …) Semantics 1. Evaluate <test1>, <test2>, … until you get to a <testi> such that <testi> evaluates to a nonNIL value 2. Evaluate <then-i-1> <then-i-2> … 3. Return value of the last <then-i-n> clause executed If all tests evaluate to NIL, result of COND is NIL CSCI Programming in Lisp; Instructor: Alok Mehta

18 Example Define a function to find area
(defun area (type r) (cond ((equal type ’circle) (* PI R R)) ((equal type ’sphere) (* 4 PI R R)) ((equal type ’square) (* R R) ((equal type ’cube) (* 6 R R)) ( t (print “Error”) )) Define a function, compute-grade, to determine the letter grade. (compute-grade 81.5) B CSCI Programming in Lisp; Instructor: Alok Mehta

19 Case Similar to COND, but is more elegant when checking for equality
(defun area (type r) (case type (circle (* PI R R)) (sphere (* 4 PI R R)) (square (* R R) (cube (* 6 R R)) (otherwise (print “Error”) )) Format (case <key-form> (<key 1> <then-1-1> <then-1-2> …) (<key 2> <then-2-1> <then-2-2> …) (<key m> <then-m-1> <then-m-2> …) (otherwise <then-o-1> <then-o-2> …) CSCI Programming in Lisp; Instructor: Alok Mehta

20 Case (2) Notes <key-form> is evaluated
But, <key 1> <key 2>, … are NOT evaluated “OTHERWISE” or “T” always evaluate to nonNIL If no matches are found, the CASE statement returns NIL A <key> form may contain a list. In this case, the <key-form> can match ANY element of the list (defun circularp (type) (case type ((circle sphere) ’T) (otherwise NIL))) (circularp ’cube) Technical note: the MEMBER function is used to do the comparison. CSCI Programming in Lisp; Instructor: Alok Mehta

21 Both-ends Revisited 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)) CSCI Programming in Lisp; Instructor: Alok Mehta

22 Solve-quadratic revisited
Solve-quadratic with error checking Checks for errors; returns NIL instead (defun solve-quadratic (a b c) (if (not (and (numberp a) (numberp b) (numberp c))) NIL ; at least one argument is not a number (let ((sqrt_clause (- (* b b) (* 4 a c))) (neg_b (- b)) (two_a (* 2 a)) ) (cond ((minusp sqrt_clause) NIL) ((= 0 a) NIL) ; Could have used zerop (t (list (/ (+ neg_b (sqrt sqrt_clause)) two_a) (/ (- neg_b (sqrt sqrt_clause)) two_a))))))) What happens if we don't include the clause (minusp sqrt_clause) … By default, Lisp arithmetic operations handle complex numbers CSCI Programming in Lisp; Instructor: Alok Mehta

23 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 f) (setf f (* f (+ i 1)))))) Note: To more easily compare, C++ loop could have been written as: for (i=0; i<x; i++) f = f * (i + 1); Tip: Compute factorial(100) using C/C++ and Lisp CSCI Programming in Lisp; Instructor: Alok Mehta

24 DoTimes DOTIMES is Lisp’s way of doing iteration C/C++ Lisp
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>) CSCI Programming in Lisp; Instructor: Alok Mehta

25 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))))) CSCI Programming in Lisp; Instructor: Alok Mehta

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

27 MEMBER MEMBER Checks if first argument is an element of second argument Returns what is left of the list when symbol is found > (setf sentence ’(tell me more about your mother please)) (TELL ME MORE ABOUT YOUR MOTHER PLEASE) > (member ’mother sentence) (MOTHER PLEASE) Only checks the top level for a match (using EQL) > (member ’mother ’((father son) (mother daughter))) NIL CSCI Programming in Lisp; Instructor: Alok Mehta

28 Example: Our-member Our-Member
(defun our-member (obj aList) (if (null aList) nil (if (eql (first aList) obj) aList (our-member obj (rest aList))))) This "design pattern" is used frequently in Lisp for recursive methods that operate on Lists (defun <recursive-function (aList) (if <base condition> <terminate with return value> <process first element> <recursively process everything except the first element>)) CSCI Programming in Lisp; Instructor: Alok Mehta

29 MEMBER; Keyword Modifiers
MEMBER tests for membership using EQL > (setf pairs ’((maple shade) (apple fruit))) > (first pairs) (MAPLE SHADE) > (member (first pairs) pairs) ((MAPLE SHADE) (APPLE FRUIT)) > (member ’(maple shade) pairs) NIL Use keyword modifier to override > (member ’(maple shade) pairs :test #’equal) :test is a keyword; it expects an argument of type procedure #’equal is a keyword argument #’ is a macro #’equal expands to (function equal) Returns the procedure object named “equal” CSCI Programming in Lisp; Instructor: Alok Mehta

30 Keywords; Procedure Macro
Why use keywords? Why not just an optional parameter? > (member ’(maple shade) pairs #’equal) Keywords allow more than one type of behavior modification :test-not is another keyword for MEMBER Why use procedure objects? Why not just allow procedure name to be passed? > (member ’(maple shade) pairs :test equal) Procedure objects can be bound to variable names > (setf predicate #’equal) > (member ’(maple shade) pairs :test predicate) Can pass them as parameters to functions, etc. CSCI Programming in Lisp; Instructor: Alok Mehta

31 Recursive Definition of Length
(defun mylength (l) (if (endp l) (+ 1 (mylength (rest l))))) Alternate definition (defun mylength2 (l) (mylength2-aux l 0)) (defun mylength2-aux (l count) count (mylength2-aux l (+ count 1)))) Note All recursive calls simply return the final value evaluated. No additional computations CSCI Programming in Lisp; Instructor: Alok Mehta

32 Tail Recursion Tail Recursion Lisp handles tail recursion efficiently
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) CSCI Programming in Lisp; Instructor: Alok Mehta

33 Produce-list-of-a Using dotimes Recursion, not tail recursive
(defun produce-list-of-a (n) (let ((la NIL)) (dotimes (i n la) (push 'A la)))) Recursion, not tail recursive (if (= n 0) nil (cons 'A (produce-list-of-a (- n 1))))) Recursion, with tail recursion (produce-list-of-a-aux n NIL)) (defun produce-list-of-a-aux (n list-so-far) list-so-far (produce-list-of-a-aux (- n 1) (cons 'A list-so-far)))) CSCI Programming in Lisp; Instructor: Alok Mehta

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

35 Tower of Hanoi Solution to Tower of Hanoi Example Runs
(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) (T S) (T E) NIL CSCI Programming in Lisp; Instructor: Alok Mehta

36 &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) (produce-list-of-a Note: optional values are bound to NIL, by default CSCI Programming in Lisp; Instructor: Alok Mehta

37 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)) (if (> n 1) (hanoi (- n 1) temp end start))) Note: notice the syntax for initializing optional parameters CSCI Programming in Lisp; Instructor: Alok Mehta

38 &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 ) 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)))) CSCI Programming in Lisp; Instructor: Alok Mehta

39 Key Parameters KEYword parameter Examples
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) CSCI Programming in Lisp; Instructor: Alok Mehta

40 &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) (rotate-list-right (append (rest l) (list (first l))) CSCI Programming in Lisp; Instructor: Alok Mehta

41 &Aux &Aux keyword is used as a shorthand for Let*
Procedures &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))) CSCI Programming in Lisp; Instructor: Alok Mehta CSCI Programming in Lisp; Instructor: Alok Mehta


Download ppt "CSCI 2210: Programming in Lisp"

Similar presentations


Ads by Google