Presentation is loading. Please wait.

Presentation is loading. Please wait.

Building user-defined functions: the progressive envelopment technique The idea: define combinations of LISP primitives through a sequence of experiments.

Similar presentations


Presentation on theme: "Building user-defined functions: the progressive envelopment technique The idea: define combinations of LISP primitives through a sequence of experiments."— Presentation transcript:

1 Building user-defined functions: the progressive envelopment technique The idea: define combinations of LISP primitives through a sequence of experiments. Thus, complex functions are build incrementally. Example: the both-ends procedure. –step 1: set a sample expressions that both-ends will work on, for example (setf whole-list '(a b c d)) –step 2: define how to get the first and last elements > (first whole-list) ==> A > (last whole-list) ==> (D) –step 3: define how to get a list of the two > (cons......) ; the results already obtained are enveloped in a cons form –step 4: envelop the cons form in a defun form with whole-list as a parameter.

2 Building user-defined functions: the comment translation technique The idea: create an outline of the function in a comment form, and then translate comments into LISP forms. Example: the both-ends procedure –step 1: write a pseudo definition for both-ends using comments instead of actual forms (defun both-ends (whole-list) ;; get the first element ;; get the last element ;; combine the two elements in a list)

3 The comment translation technique (cont.) –step 2: gradually translate the comments into LISP forms (defun both-ends (whole-list) (first whole-list) (first (last whole-list)) ;; combine the two elements in a list) –step 3: complete the comment translation (defun both-ends (whole-list) (list (first whole-list) (first (last whole-list))))

4 Binding parameters to initial values: the LET primitive The general format of the let form is the following: (let (( ) … ( )) … ) Example: > (setf whole-list ’(a b c d)) > (let ((first-el (first whole-list)) (last-el (last whole-list))) (cons first-el last-el)) (A D)

5 Let can be used within defun but let parameters are local to the let form Example: > (defun both-ends-with-let (whole-list) (let ((first-el (first whole-list)) (last-el (last whole-list))) (cons first-el last-el))) BOTH-ENDS-WITH-LET > (both-ends-with-let whole-list) (A D) > (defun both-ends-with-let (whole-list) (let ((first-el (first whole-list)) (last-el (last whole-list))) (cons first-el last-el)) (print first-el)) BOTH-ENDS-WITH-LET > (both-ends-with-let whole-list) ;; Error: Unbound variable FIRST-EL in BOTH-ENDS-WITH-LET

6 Let evaluates its initial-value forms in parallel before any let parameter is bound, while LET* does this sequentially Example: > (setf x 'first-value) FIRST-VALUE > (let ((x 'second-value) (y x)) (list x y)) (SECOND-VALUE FIRST-VALUE) > (let* ((x 'second-value) > (let ((x ‘second-value)) (y x)) or (let ((y x)) (list x y)) equivalent (list x y))) (SECOND-VALUE SECOND-VALUE)

7 Predicates for establishing equality between arguments EQUAL : tests two arguments to see if their values are the same expression. > (equal (+ 5 5 5) 15) T > (setf list-1 '(This is a list)) (THIS IS A LIST) > (equal '(This is a list) list-1) T > (equal 15 15.0) ; 15 and 15.0 have different NIL ; internal representations EQUALP: tests two arguments to see if they are the same expression ignoring case and data type differences > (equalp 15 15.0) T > (equalp '(THIS IS 1) '(this is 1)) T

8 Equality predicates (cont.) EQL : tests two arguments are the same atom (i.e. number or symbol). > (eql 'atom-1 'atom-1) T > (eql 15 15) T > (eql 15 15.0) ; 15 and 15.0 are not the same atom NIL = : tests to see if two arguments are the same number. > (= 15 15.0) T EQ : tests to see if two arguments are the same symbol, i.e. if they are represented by the same chunk of computer memory. They will be, if they are identical symbols; numbers are not always represented by the same memory address.

9 Member : a predicate for testing whether the first argument is an element of the second argument Example: > (setf list-1 '(It is a nice day)) (IT IS A NICE DAY) > (member 'day list-1) (DAY) > (member 'is list-1) (IS A NICE DAY) > (member 'is '((It is) (a nice day))) NIL Note: Member works only on top-level elements.

10 Member tests arguments with eql > (setf pairs '((a b) (c d) (e f))) ((A B) (C D) (E F)) > (member '(c d) pairs) ; member fails to identify list membership of a list NIL To modify the basic behavior of member, an appropriate keyword argument must be used. > (member '(c d) pairs :test #'equal) ((C D) (E F)) > (member '(c d) pairs :test-not #'equal) ((A B) (C D) (E F)) > (member '(a b) pairs :test-not #'equal) ((C D) (E F)) > (member '(c d) '((c d) (c d)) :test-not #'equal) NIL

11 Keywords are self-evaluated symbols; they always start with : > :test :TEST ; keywords evaluates to themselves > test ; symbols evaluate to the value stored in the variable named by the ; symbol ;; Error: Unbound variable TEST in # Keyword arguments act as variables, storing procedure objects. > (setf predicate #'equal) ; #'equal produces a procedure object out of # ; procedure name equal. > (member '(c d) pairs :test predicate) ((C D) (E F))

12 More examples Keyword arguments can act as variables; this makes it possible to specify any keyword argument. > (member 4.0 '(6 7 8 4 9)) NIL > (setf predicate #'=) # > (member 4.0 '(6 7 8 4 9) :test predicate) (4 9) > (setf predicate #'equalp) ; equalp ignores case distinctions and # ; data types; the most liberal equality > (member 4.0 '(6 7 8 4 9) :test predicate) ; predicate (4 9)

13 Predicates for testing object types Atom : tests to see if the argument is an atom. > (atom 'pi) T > (atom pi) ; pi has a built-in value of 3.14159265358979 T Numberp : tests to see if the argument is a number. > (numberp 'pi) NIL > (numberp pi) T Symbolp: tests to see if the argument is a symbol. > (symbolp 'pi) T > (symbolp pi) NIL

14 Predicates for testing object types (cont.) Listp : tests to see if the argument is a list. > (listp 'pi) NIL > (listp '(pi in a box)) T Consp : tests to see if the argument is a non-empty list. > (consp '()) NIL > (consp nil) NIL > (consp '(a non-empty list)) T > (consp '(a. b)) T

15 Predicates for testing for an empty list Null : tests to see if the argument is an empty list. > (null '(not an empty list)) NIL > (null 'a) ; the argument can be an atom NIL > (null nil) T > (null ()) T Endp : tests to see if the argument is an empty list > (endp '(not an empty list)) NIL > (endp ()) T > (endp 'a) ; the argument must be a list T ; this is a surprising result - the expected result is an error.

16 Numerical predicates n Numberp : tests to see if the argument is a number. n Zerop : tests to see if the argument is zero. n Plusp : tests to see if the argument is a positive number. n Minusp : tests to see if the argument is a negative number. n Evenp : tests to see if the argument is an even number. n Oddp : tests to see if the argument is an odd number. n > : tests to see if the arguments are in descending order. n < : tests to see if the arguments are in acsending order. > (plusp (- 7)) > (> 8 6 4 2) NIL T > (evenp (* 9 5)) > (< 1 3 5 7) NIL T > (oddp (* 9 5)) > (> 1 3 5 7) T NIL

17 Results of two or more predicates can be combined by means of AND, OR and NOT primitives n And : returns NIL if any of its arguments is NIL, otherwise returns the value of the last argument > (setf list-1 '(a b c d)) (A B C D) > (and (member 'a list-1) (member 'c list-1)) (C D) > (and (member 'e list-1) (member 'c list-1)) NIL n Or : returns NIL if all arguments are NIL, otherwise retrurns the value of the first non-NIL argument. > (or (member 'e list-1) (member 'c list-1)) (C D) > (or (member 'e list-1) (member 'a list-1) (member 'c list-1)) (A B C D)

18 Logical predicates (cont.) n Not : returns T if its argument is NIL. > (not nil) T > (not ()) T > (not (member 'c '(a b d e))) T > (not (member 'c '(a b c d))) NIL Not behaves the same way as the Null predicate, because NIL and the empty list ( ) is one and the same thing.

19 Conditionals : the if, when and unless forms n If has the following format : (if ) Example: > (setf symbol-or-number 'name) NAME > (if (symbolp symbol-or-number) 'symbol 'number) SYMBOL > (setf symbol-or-number '7) 7 > (if (symbolp symbol-or-number) 'symbol 'number) NUMBER

20 Conditionals (cont.) n When has the following format: (when ) This is equivalent to (if NIL). n Unless has the following format: (unless ) This is equivalent to (if NIL ). Note: both when and unless may have unlimited number of arguments, where the first argument is always the test, the last argument supplies the value to be returned, and all others are evaluated for their side effects.

21 Example > (setf high 98 temperature 102) 102 > (when (> temperature high) (setf high temperature) 'new-record) NEW-RECORD > high 102

22 Cond selects among alternatives The general form of cond is the following: (cond (... ) (... ).... (... )), where (... ) is called a clause. A clause whose test is evaluated to non-NIL is said to be triggered, and its consequents are evaluated. None of the rest clauses is evaluated.

23 Example: compute the area of object which can be a circle or a sphere > (setf object 'sphere R 1) 1 > (cond ((eq object 'circle) (* pi r r)) ((eq object 'sphere) (* 4 pi r r))) 12.5663706143592 The cond form has the following equivalent formats: > (cond ((eq object 'circle) (* pi r r)) (t (* 4 pi r r))) 12.5663706143592 > (cond ((eq object 'circle) (* pi r r)) ((* 4 pi r r))) ; here (* 4 pi r r) is both the test, and the 12.5663706143592 ; consequent.

24 More examples > (setf p.6) 0.6 > (cond ((> p.75) 'very-likely) ((> p.5) 'likely) ((> p.25) 'unlikely) (t 'very-unlikely)) LIKELY > (setf breakfast '(eggs bacon toast tea)) (EGGS BACON TOAST TEA) > (cond ((> (length breakfast) 10) 'very-hungry) ((not (endp breakfast)) 'just-hungry) (t 'not-hungry)) JUST-HUNGRY

25 Write a procedure check-temperature which takes one numerical argument, and returns VERY-HOT if argument value is greater than 100, VERY-COLD if it is less than 0, and NORMAL otherwise. > (defun check-temperature (temp) (cond ((> temp 100) 'very-hot) ((< temp 0) 'very-cold) ('normal))) CHECK-TEMPERATURE > (check-temperature 150) VERY-HOT > (check-temperature 95) NORMAL > (check-temperature (- 7)) VERY-COLD


Download ppt "Building user-defined functions: the progressive envelopment technique The idea: define combinations of LISP primitives through a sequence of experiments."

Similar presentations


Ads by Google