160 likes | 302 Views
Mapping And Iteration. So far, the only Lisp mechanism we have considered, which allows an action to be performed repeatedly is recursion. Most programming languages also have non-recursive constructs which allow the programmer to specify that an action is to be repeated. Mapping Functions.
E N D
Mapping And Iteration • So far, the only Lisp mechanism we have considered, which allows an action to be performed repeatedly is recursion. • Most programming languages also have non-recursive constructs which allow the programmer to specify that an action is to be repeated
Mapping Functions Mapping functions are used when: • The repetition is for each element (or subpart) of a list; • The computation to be done each time is easily expressible as a function • MAPCAR, MAPC
MAPCAR • This function takes a function as an argument and applies it to all items of a given list, returning as a result a list of al the results thus obtained: To reverse each element of a list: > (mapc #’reverse ‘ ( (a b) (c d) (e f) (g h) ) ) ( (b a) (d c) (f e) (g h) ) >(mapcar #’first ‘( (a b) (c d) (e f))) (a c e) >(mapcar #’rest‘( (a b) (c d) (e f))) ( (b) (d) (f) ) >(mapcar #’second‘( (a b) (c d) (e f))) ( b d f )
MAPCAR with multiple lists We can give more than one list as argument to mapcar. Mapcar will apply the function to the corresponding elements in all the lists. For example, to add the corresponding elements in two lists: (mapcar #’+ (2 5 4) (10 11 12) (7 8 9)) (19 24 23) If we do this with lists of different lengths, mapcar will stop when it reaches the end of the shortest list: (mapcar #’+ (2) (10 11 12) (7 8 9)) (19)
This anonymous function returns every element except the one we’re removing. Each returned element is placed in a list Mapcar applies the function to each element in list1 and returns all results Since the function returns each element in a list (and an empty list for skipped elements), we have to append all the returned lists together Mapcar example: remove elements iteratively > (remove_iterative ‘b ‘(a b c d b e f b)) (a c d e f) This can be done by: (defun remove_iterative (x list1) (apply #’append (mapcar #’(lambda (element) (cond ((equal x element) ‘()) (t (list element)) ) ) list1 ) ) )
MAPC • MAPC is like MAPCAR, but it doesn’t return a list of results. • MAPC is used where the side-effect of the computation is required, but where the overall result of the computation is irrelevant. If the function given to MAPC needs more than one argument, then there should be as many lists of values supplied as it takes arguments: (mapc <function> <arguments-1><arguments-2>…<arguments-N>)
MAPC example To print out all the items in the list listofvalues, each on a new line (where terpri outputs a new line), in between angle brackets: (defun printValues(listofvalues) (mapc #’(lambda (x) (print “<“) (print x) (print “>“) (terpri) ) listofvalues ) )
MAPC example: (mapc #’(lambda ( x y) (cond ((not (eql x y)) (print (list x y)))) ) ‘(4 6 7 11 2) ‘(3 6 7 10) ) (4 3) (11 10) Notice that if the lists are not all the same length, then the repetition terminates once the shortest list has been used up; the different lengths do not cause an error We have to use print to find out the results from MAPC: it doesn’t return the results in a list. MAPCAR is usually preferred.
a b c d e f value Left node Right node Representing trees in lisp This is a tree. How would we represent a tree like this in Lisp? With lists. Each list represents a node in the tree, containing the node’s value and its left and right subnodes ( a ) ( b ) ( d ‘() ‘() ) ( e ‘() ‘() ) ( c ‘() ) ( e ‘() ‘() )
EXAMPLE EXERCISE: • Functions for a tree-node data type: ;; node-value: function taking as argument a list representing a node ;; returns associated value of a node (defun node-value (node) (first node)) ;; node-left: function taking as argument a list representing a node ;; returns left –daughter node if any (defun node-left (node) (second node)) ;; node-right: function taking as argument a list representing a node ;; returns right-daughter node if any (defun node-left (node) (third nd))
EXAMPLE – EXERCISE (cont.): ;; terminal: function taking as argument item representing a node ;; returns T if no daughters of that node (the bottom of the tree) (defun terminal (node) (and (null (node-left node)) (null (node-right node))) ) ;; search-tree: function taking two arguments: 1. A node in a tree & ;; 2. An atom to be sought in the tree from that node downwards. ;; returns the sub tree which has that atom as its root (defun search-tree (tree target) (cond ((equal target (node-value tree)) tree) ; found it ((terminal tree) nil) ; run out of tree to search (t (or (search-tree (node-left tree) target) (search-tree (node-right tree) target)))))
EXAMPLE – EXERCISE (cont.): • How would you write a function GET-ALL-VALUEs that takes a node and returns all the values in the tree with that node at its root (its top node?) • Best to do this recursively!!! (defun get-all-values (node) (if (terminal node) (list (get-value node)) (apply #'append (get-all-values (node-left node)) (list (get-value node)) (get-all-values (node-right node)) ) ) )
EVERY The EVERY function operates in a similar way to MAPCAR, but is used for logical checking. The EVERY function returns a non-NIL result if the function supplied yields a non-NIL result on every element of the list > (every #’numberp ‘(2 5 3 6)) t > (every #’numberp ‘(2 hello 3 5)) nil > (every #’= ‘(2 4 6) (list ( - 3 1) (+ 2 2) (* 2 3))) t
SOME This function returns a non-NIL result if the function yields a non-NIL result on some element of the list (or lists). > (some #’numberp ‘(a b 3 4)) t > (some #’numberp ‘(hello and welcome)) nil > (some #’= ‘(3 4 5) (list (-3 1) (+2 2) (*2 3))) t
Optional parameters • It can sometimes be useful to define a function so that one or more arguments can be omitted in some of the uses of the function. For example: > (mklist 9) > (9) > (mklist 9 ‘(1 2 3)) > (9 1 2 3) > (mklist 9 nil) > (9) How this can be done? Optional arguments
Optional arg called y Default value for y, used if none is given Optional parameters (cont.) (defun function-name (req-arg &optional (optional-arg default-value) ) do whatever the function does ) Caller has to give a value for req-arg. If they give a second arg it goes into optional-arg. Otherwise, opt-arg takes on given default-value. • (defun f (x &optional (y 10)) • (list x y)) > (f 2) (2 10) > (f 2 5) (2 5)