320 likes | 473 Views
66-2210-01 Programming in Lisp. Procedures, Variables, Conditionals. Procedure Declaration. Simple procedure in C/C++ to square a number double sqr (double x) { return x * x; } Equivalent function in Lisp (defun sqr (x) (* x x)) Note C/C++ implementation is strongly typed; Lisp is not
E N D
66-2210-01 Programming in Lisp Procedures, Variables, Conditionals 66 2210 - Programming in Lisp; Instructor: Alok Mehta
Procedure Declaration • Simple procedure in C/C++ to square a number • double sqr (double x) { • return x * x; • } • Equivalent function in Lisp • (defun sqr (x) (* x x)) • Note • C/C++ implementation is strongly typed; Lisp is not • Value returned by procedure is the last expression evaluated • (defun sqr (x) • (+ 2 3) • (* 7 8) • (+ x 3) • (* x x)) 66 2210 - Programming in Lisp; Instructor: Alok Mehta
Defun • Defun is a Lisp procedure • (defun <proc-name> • (<parameter1> <parameter2> ...) • <expression1> <expression2> ...) • Side effect • defines a user-defined lisp procedure • Returns the name of the procedure defined • Defun does not evaluate its arguments • Resulting user-defined procedure is used like any other Lisp procedure • > (defun sqr (x) (* x x)) • SQR • > (sqr 5) • 25 66 2210 - Programming in Lisp; Instructor: Alok Mehta
Scope • Consider • > (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) • > (list a b c) • (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 66 2210 - Programming in Lisp; Instructor: Alok Mehta
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) • 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 66 2210 - Programming in Lisp; Instructor: Alok Mehta
Let • Let = Lisp’s way of defining local variables • (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)) ) 66 2210 - Programming in Lisp; Instructor: Alok Mehta
Let vs. Let* • Let - Parallel evaluation • > (setf x ’outside) • OUTSIDE • > (let ((x ’inside) (y x)) (list x y)) • (INSIDE OUTSIDE) • Let* - Sequential evaluation • > (setf x ’outside) • OUTSIDE • > (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)) ) 66 2210 - Programming in Lisp; Instructor: Alok Mehta
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 1 -2 1) • (1.0 1.0) 66 2210 - Programming in Lisp; Instructor: Alok Mehta
Progressive Envelopment • Build up complex expressions incrementally • Technique of “Bottom-Up Design” • x1 = (-b + sqrt (b^2 - 4ac)) / 2a • > (setf a 1 b -2 c 1) • 1 • > (* b b) • 4 • > (* 4 a c) • 4 • > (- (* b b) (* 4 a c)) • 0 • > (setf sqrt_clause (sqrt (- (* b b) (* 4 a c)))) • 0 • > (setf neg_b (- b)) • 2 • > (setf two_a (* 2 a)) • 2 • > (setf x1 (/ (+ neg_b sqrt_clause) two_a)) • 1 66 2210 - Programming in Lisp; Instructor: Alok Mehta
Progressive Envelopment (2) • Solution to solve-quadratic • (defun solve-quadratic (a b c) • (let ((sqrt_clause (sqrt (- (* b b) (* 4 a c)))) • (neg_b (- b)) • (two_a (* 2 a)) ) • (list (/ (+ neg_b sqrt_clause) two_a) • (/ (- neg_b 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 • Conditionals - to do something else when error occurs 66 2210 - Programming in Lisp; Instructor: Alok Mehta
Comment Translation • Break down the problem incrementally • Technique of “Top-Down Design” • x1 = (-b + sqrt (b^2 - 4ac)) / 2a • Steps to solve this: • ; Solve for x1 • ; Solve for x2 • ; Combine solutions into a list • Break down problem of solving for x1 • ; Evaluate Numerator • ; Evaluate Denominator • ; Divide Numerator / Denominator • Break down problem of solving for Numerator • ; Evaluate -b • ; Evaluate sqrt clause • Break down problem of solving for sqrt clause • ; Evaluate b^2 • ; Evaluate 4ac • ; Subtract b^2 - 4ac • ; Take the square root 66 2210 - Programming in Lisp; Instructor: Alok Mehta
Comment Translation (2) • Continue refining solution until it is easy to solve • ; Evaluate b^2 • (* b b) • ; Evaluate 4ac • (* 4 a c) • ; Subtract b^2 - 4ac • (- (* b b) (* 4 a c)) • ; Take the square root • (sqrt (- (* b b) (* 4 a c))) 66 2210 - Programming in Lisp; Instructor: Alok Mehta
Predicates; Equal • Predicate - Procedure that returns true or false • false is represented by NIL • true is represented by T (or, anything else) • Equal - Are two argument values the same expr? • > (equal (+ 2 2) 4) • T • > (equal (+ 2 2) 3) • NIL • > (setf l ’(this is a list)) • (THIS IS A LIST) • > (equal l (reverse ’(list a is this))) • T 66 2210 - Programming in Lisp; Instructor: Alok Mehta
EQUAL does not = EQL • Several predicates check equality • Slightly different semantics • More efficient than EQUAL • 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? 66 2210 - Programming in Lisp; Instructor: Alok Mehta
Relationships Bet Equality Pred’s EQUAL F • 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 4.0 4.0) ;; EQ:NIL =:T (A) = EQL A EQ D E B C 66 2210 - Programming in Lisp; Instructor: Alok Mehta
EQL vs. = • EQL • Arguments are EQL if they are either EQ or they are equivalent numbers of the same type • Examples • > (eq 4.0 4.0) ;; 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 66 2210 - Programming in Lisp; Instructor: Alok Mehta
EQUAL vs. EQL 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 66 2210 - Programming in Lisp; Instructor: Alok Mehta
Equality; MEMBER • Checking for Equality • Semantics can be confusing • General Rule of Thumb • Use = when you want to compare numbers • Use EQUAL otherwise • 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)) • > (member ’mother sentence) • (MOTHER PLEASE) • Only checks the top level for a match (using EQL) • > (member ’mother ’((father son) (mother daughter))) • NIL 66 2210 - Programming in Lisp; Instructor: Alok Mehta
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) • ((MAPLE SHADE) (APPLE FRUIT)) • :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” 66 2210 - Programming in Lisp; Instructor: Alok Mehta
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. 66 2210 - Programming in Lisp; Instructor: Alok Mehta
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) • (3.14159 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) 66 2210 - Programming in Lisp; Instructor: Alok Mehta
NIL Revisited; NULL, ENDP • NIL is a (empty) list • > (eq nil ’()) ; T • > (eql nil ’()) ; T • > (equal nil ’()) ; T • > nil ; NIL • > () ; NIL • > (atom nil) ; T • > (symbolp nil) ; T • > (listp nil) ; T • NULL, ENDP - Return T if argument is an empty list • ENDP Causes error if argument is not a list • > (null nil) ; T • > (endp nil) ; T • > (null ’(this is not empty)) ; NIL • > (endp ’(this is not empty)) ; NIL • > (null ’ABC) ; NIL • > (endp ’ABC) ; ERROR 66 2210 - Programming in Lisp; Instructor: Alok Mehta
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? • Note: Predicates often end in the letter “p” • Coffeep? Endclassp? 66 2210 - Programming in Lisp; Instructor: Alok Mehta
And, Or, Not • And, Or • Used to combine predicates • Shortcut evaluation • Stops processing as soon as the answer is known • > (and (ARG1) (ARG2) NIL (ARG3)) • ARG3 is never evaluated! • > (or (ARG1) (ARG2) T (ARG3)) • ARG3 is never evaluated! • Returns the value of the last expression evaluated • > (and 3 4 NIL 9 (+ 3 2)) ; Returns NIL • > (and 3 4 5 9 (+ 3 2)) ; Returns 5 • > (or NIL (+ 3 2) NIL 4 8) ; Returns 5 • Not • Changes NIL to T; Changes everything else to NIL 66 2210 - Programming in Lisp; Instructor: Alok Mehta
Exercises • Define palindromep • If elements of a list read the same from left-to-right as they do from right-to-left, return true. • (palindromep ’(a b c d d c b a)) • T • (palindromep ’(a b c b a) • T • (palindromep ’(a b b c)) • NIL 66 2210 - Programming in Lisp; Instructor: Alok Mehta
If • If • Template • (if <test> <then-form> <else-form>) • Example • (defun solve-quadratic (a b c) • (let ((clause (sqrt (- (* b b) (* 4 a c)))) • (neg_b (- b)) • (two_a (* 2 a)) ) • (if (minusp clause) • NIL • (list (/ (+ neg_b (sqrt clause)) two_a) • (/ (- neg_b (sqrt clause)) two_a))))) • Either the second argument or the third argument are evaluated • Never both! • IF is a Conditional - result depends on value of <test> 66 2210 - Programming in Lisp; Instructor: Alok Mehta
If, When, Unless • If • (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. 66 2210 - Programming in Lisp; Instructor: Alok Mehta
Exercises • Write function to find the maximum of two numbers • Write function to take the absolute value of two numbers. 66 2210 - Programming in Lisp; Instructor: Alok Mehta
Cond • Cond format • (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 66 2210 - Programming in Lisp; Instructor: Alok Mehta
Example • Define a function to find area • (defun area (type r) • (cond ((eq type ’circle) (* PI R R)) • ((eq type ’sphere) (* 4 PI R R)) • ((eq type ’square) (* R R) • ((eq type ’cube) (* 6 R R)) • ( t (print “Error”) )) • Define a function, compute-grade, to determine the letter grade. • (compute-grade 81.5) • B 66 2210 - Programming in Lisp; Instructor: Alok Mehta
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> …) 66 2210 - Programming in Lisp; Instructor: Alok Mehta
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 MEMBER function is used to do the comparison. • (defun circularp (type) • (case type • ((circle sphere) ’T) • (otherwise NIL))) • (circularp ’cube) 66 2210 - Programming in Lisp; Instructor: Alok Mehta