Control in LISP Functions Predicates Conditionals LISP n
- Slides: 39
Control in LISP Functions Predicates Conditionals
LISP n Function model – mapping from one domain to another – give arguments – get result Need to create functions n Need to specify mapping n
Function Parts n Name of the function – a symbol (atom, but not a number) Parameters of the function n Mapping from arguments to result n – built by composition – putting other functions together
Both-Ends Function n Return first & last elements of the argument > (both-ends ‘(a b c d e)) (A E) n Method: get the first element & list containing the last element & join them > (cons (first ‘(a b c d e)) (last ‘(a b c d e))) (A E)
Define Function n DEFUN special form: – DEfine a FUNction Does not evaluate its arguments n 1 st argument = function name n 2 nd argument = list of parameters n 3 rd argument = body of function n – another function call
Both-Ends Definition (defun both-ends function name (L) list of parameters (cons (first L) (last L))) n body of function Usually written with name & parameters on same line as defun (defun both-ends (L) name & parameters (cons (first L) (last L))) body of function
Defun Special Form n Returns name of function as its value – mostly we don’t care n Creates a new function object – functions are “first class objects” in LISP n Attaches the function to the name – note: not as its value
Function Call Symbol that has been defunned can be used as a function n Argument(s) get matched with parameters n – by position – just like most languages n Body gets called – parameter evaluates to the argument n Returns result of inner function call
Function Call (both-ends ‘(a b c d)) L gets bound to (A B C D) (cons (first L) (last L)) (cons (first (A B C D)) (last (A B C D))) (cons A (D)) (A D) returns (A D) as its value L no longer bound to (A B C D)
Function Body n Function body is almost always one call – multiple calls only useful for side effects – side effects bad n Arguments of inner call usually based on parameters
Exercise n Define a Fahrenheit to Celsius conversion function: – (f-to-c 32) returns 0 – °C = (°F – 32) * 5/9
Multiple Parameters n Just like in other languages – values assigned in order > (defun three-firsts (A B C) (list (first A) (first B) (first C))) THREE-FIRSTS > (three-firsts ‘(a b c) ‘(1 2 3) ‘(do re mi)) (A 1 DO) A was bound to ‘(a b c) B was bound to ‘(1 2 3) C was bound to ‘(do re mi)
Parameters as Local Variables n Parameters are local to the function – doesn’t change value of atom with same name > (setf a ‘(something other than ‘(a b c))) (SOMETHING OTHER THAN ‘(A B C)) > (three-firsts ‘(a b c) ‘(1 2 3) ‘(do re mi)) (A 1 DO) >a (SOMETHING OTHER THAN ‘(A B C))
Exercise n What values do the following return – called in the order shown > (setf a ‘(something other than (a b c))) > (setf b ‘(this is the value of b)) > (setf c ‘(said hey)) > (three-firsts a b c) > (three-firsts ‘(a b c) (append a b c) (list a b c))
Predicates n Functions that return true or false – false = NIL – true = T (actually, anything other than NIL) > (equal (+ 4 5 6) (* 3 5)) T > (equal (+ 4 7 10) (* 3 5)) NIL n T and NIL both evaluate to themselves
Numeric Comparisons n Can test numbers for <, >, <=, >= – functions have same names > (< 10 20) T > (list (< 20 10) (> 20 10) (<= 20 20) (>= 10 9)) (NIL T T T) n Also have = for numeric equality – only works on numbers
Multi-Argument Versions n < actually means “monotone increasing” – every argument less than one after it – similarly for other comparisons > (< 10 20 30 40 50 60 70 80 90 100) T > (>= 10 9 8 8 8 5 4 3 1 0 0) T = takes multiple arguments EQUAL takes exactly 2 arguments
Member Predicate n Member returns whether 1 st argument in 2 nd – 1 st usually an atom, 2 nd must be a list > (member 15 ‘(5 10 15 20 25) (15 20 25) n Returns part of list that starts with the element given – NIL if there is no such element
Member’s Return Value n Returning the list is helpful – may want to see if it’s there again – “count how many times it appears in the list” n Returns NIL (empty list, false) if not there
Exercise n Write a function twice-member that says whether its first argument is in its second twice (it will return only the part of the list starting at the second occurrence) > (twice-member ‘a ‘(s a d f a w e)) (A W E) > (twice-member ‘a ‘(w e r a w o)) NIL
Solution n Only there twice if it’s a member of the tail of the list member returns first > (member ‘a ‘(s a d f a w e)) (A D F A W E) > (member ‘a ‘(d f a w e)) (A W E) (member ‘a ‘(s a …)) (rest (member ‘a ‘(s a …)))
Solution (Continued) (defun twice-member (E L) (member E (rest (member E L)))) n Calls run from inside out – just like in imperative languages n 1 st: member E L may return nil n 2 nd: rest (member E L) nil if above was nil n 3 rd: member (…) nil if above was nil
Testing for NIL n To see if a list is empty use NULL > (null ‘(s a d f a w e)) NIL > (null ()) T n Returns NIL if argument is not a list > (null ‘a) NIL
Exercise n Write a function non-member that says that its first argument is not a member of the second > (non-member ‘a ‘(s a d f w e)) NIL > (non-member ‘a ‘(d f w e)) T
Conditionals n LISP has multiple conditional statements – choose a value based on a condition n All conditionals are special forms – don’t want to evaluate parts not selected n Conditional special forms: – if, when, unless, cond
IF Statements n IF takes three arguments – condition to test – value to return if true (anything other than NIL) – value to return if false (NIL) > (if (member ‘a ‘(s a d f a w e)) 1 – 1) 1 > (if (null ‘(s a d f a w e)) ‘empty ‘not-empty) NOT-EMPTY
IF Special Form n Unchosen alternative is not evaluated at all – not executed – no side effects > (setf a 10) > (setf b 20) > (if (< a b) (setf a 0) (setf b 0)) 0 Did not evaluate (setf b 0) >b This is exactly the way you’d want it 20
Exercise Write a conditional form that returns the larger of two numbers n Write a function MAX 2 that returns the larger of its two arguments n
When and Unless Special Forms n (WHEN <condition> <true-part>) – returns value of <true-part> if condition is true – returns NIL if condition is false – same as (IF <condition> <true-part> NIL) n (UNLESS <condition> <false-part>) – returns value of <false-part> if condition is false – returns NIL if condition is true – same as (IF <condition> NIL <false-part>)
COND Special Form n If is a bi-conditional – goes one of two ways n When and unless are simple conditionals – do it or not n Cond is a multi-conditional – goes lots of ways – if C 1 then T 1 else-if C 2 then T 2 else-if C 3…
Multi-Way Conditional (COND (C 1 T 1) (C 2 T 2) (C 3 T 3) … (Cn Tn)) if (C 1) then T 1 else if (C 2) then T 2 else if (C 3) then T 3 … else if (Cn) then Tn Executes the first Ti whose corresponding Ci is true True = not NIL, for LISP
Example n Write a function that returns the word for its (numeric) argument, from 1 to 5 (defun number-word (N) (cond ((equal N 1) ‘one) ((equal N 2) ‘two) ((equal N 3) ‘three) ((equal N 4) ‘four) ((equal N 5) ‘five))) Returns NIL if N is not one of these numbers Note “double” parentheses – first element of each pair is a condition
Default Condition n Condition can be anything – T is a condition – always true – use T as last condition for “else” condition (cond ((null P) ‘zero) ((equal (length P) 1) ‘one) ((equal (length P) 2) ‘two) (T ‘more-than-two)
Recursion n We can now write recursive functions (defun factorial (N) (if (equal N 1) 1 (* N (factorial (– N 1))) ) )
Recursion n Write a recursive function to calculate the Fibonacci number of N (defun fibonacci (N) (cond ((equal N 0) 0) ((equal N 1) 1) (T (+ (fibonacci (– N 1)) (fibonacci (– N 2)) ) )
Building an Answer n Write a function that adds one to every element of a list – (add-1 -all ‘(1 2 3 9 5 2)) returns (2 3 4 10 6 3) n Method: make a list that consists of – one more than the first element of the list – the rest of the list, with one added to each element
Down to Cases n Base case is if the list is empty – return the empty list n Recursive case needs to construct a list – use cons (element + list longer list) – 1 st argument is 1 more than first argument – 2 nd argument got recursively
Add-1 -All Suppose L = (1 2 8 4) (defun add-1 -all (L) L is not empty (if (null L) () this gives us the 2 (cons (+ 1 (first L)) this gives us the (3 9 5) (add-1 -all (rest L)) ) cons puts the 2 & the (3 9 5) together function returns (2 3 9 5) as its value
Next Time n More Control in LISP – Chapters 4, 5 & 7
- Cond in lisp
- Procedural versus declarative knowledge in ai
- Complete subject and simple subject
- Draw a line between the complete subject and predicate
- Subjects and predicates
- What are simple predicates
- What are simple predicates
- Compound subject and predicate
- Predicates and quantifiers
- Compound subjects
- Minterm predicate
- Predicate and predicator
- Lesson 4 subjects and predicates simple and complete
- Compound subject
- Lesson 4 compound subjects and predicates
- Applications of predicates and quantifiers
- Transition and transfer predicates
- Transition and transfer predicates
- Lisp cond
- Lisp unless
- Mcapply
- Lisp and prolog
- Lisp polish notation
- Contenes
- Lisp map resolver
- Cons in lisp
- Positive list scheme
- Cons in lisp
- Lisp list processing
- Lisp lists
- Emacs scheme
- Xkcd lisp
- Common lisp association list
- Xkcd lisp
- Lisp jvm
- Fortran interpreter
- Lisp and prolog
- Introduction to lisp
- Allegro write program
- Common lisp car