Date post: | 31-Dec-2015 |
Category: |
Documents |
Upload: | byron-small |
View: | 230 times |
Download: | 2 times |
IterationIteration
Chapters 6 & 7Chapters 6 & 7
Iteration in LISPIteration in LISP
LISP (unlike Prolog) allows iterationLISP (unlike Prolog) allows iteration– mapcar, remove-if(-not), count-if, find-if for mapcar, remove-if(-not), count-if, find-if for
special purpose iterationspecial purpose iteration Dotimes, dolist & do allow more general Dotimes, dolist & do allow more general
iterationiteration– often used with side-effectsoften used with side-effects
Review of DoReview of Do
Do takes list of local variables, stopping Do takes list of local variables, stopping condition plus return expression and bodycondition plus return expression and body> > (do ((i 1 (1+ i)))(do ((i 1 (1+ i)))
((> i 10) ‘done)((> i 10) ‘done) (format t “~a ” i)) (format t “~a ” i))
1 2 3 4 5 6 7 8 9 10 1 2 3 4 5 6 7 8 9 10 DONEDONE
DoTimes ExampleDoTimes Example
Exponentiation functionExponentiation function– (power 5 3) => 125(power 5 3) => 125
(defun power (M N)(defun power (M N)
(setf result 1)(setf result 1)
(dotimes (i N result) (setf result (* M result))))(dotimes (i N result) (setf result (* M result))))
extra form in defunjust for the side effect
body of the loopdone for the side effect
loop control variable
upper bound of the loop
return value
DoTimes OperationDoTimes Operation
(dotimes ((dotimes (i i NN resultresult) ) <body><body>))
(dotimes (i N res)(dotimes (i N res)(setf res (* M res)))(setf res (* M res)))
for ( for ( ii = 0; = 0; ii < < NN; ; ii++ ) ++ ) <body><body>
return return resultresult;;
for ( i = 0; i < N; i++)for ( i = 0; i < N; i++)res = M * res;res = M * res;
return res;return res;Loop control variable is not evaluatedUpper bound is evaluated before 1st iterationReturn result is evaluated after last iterationBody evaluated once per iteration
DoTimes FactorialDoTimes Factorial
Loop control variable available in the loopLoop control variable available in the loop– just like loop control in imperative languagesjust like loop control in imperative languages
(defun factorial (N)(defun factorial (N)
(setf fact 1)(setf fact 1)
(dotimes (i N fact)(dotimes (i N fact)
(setf fact (* (1+ i) fact))))(setf fact (* (1+ i) fact))))
Need to add 1 to i, because i runs from 0 to N–1, not 1 to N
ExerciseExercise
Write a function using dotimes to calculate Write a function using dotimes to calculate the sum of the numbers from 1 to Nthe sum of the numbers from 1 to N– can you do it without adding 1 to i each time?can you do it without adding 1 to i each time?
SolutionSolution
(defun sum-to-N (N)(defun sum-to-N (N)
(setf sum 0)(setf sum 0)
(dotimes (i (1+ N) sum)(dotimes (i (1+ N) sum)
(setf sum (+ sum i))))(setf sum (+ sum i)))) Run loop to N+1 so we get sum 0..NRun loop to N+1 so we get sum 0..N
– 0 adds nothing to the sum, so that’s OK0 adds nothing to the sum, so that’s OK Alternative: Alternative: (dotimes (i N (+ sum N)) (dotimes (i N (+ sum N)) ……))
Local Local vs. vs. Global VariablesGlobal Variables
Functions above use global variablesFunctions above use global variables– not good – what if someone was using them not good – what if someone was using them
already?already?– what if one of the functions called uses the what if one of the functions called uses the
samesame global variable? global variable? Would like all the variables to be localWould like all the variables to be local LISP gives us let and let*LISP gives us let and let*
LetLet
Let defines & initializes local variablesLet defines & initializes local variables> > (let ((v1 10) (v2 5)) (+ v1 v2))(let ((v1 10) (v2 5)) (+ v1 v2))
1515
> > v1v1
ERROR: undefined variableERROR: undefined variable (let <list-of-variable-value-pairs> <body>)(let <list-of-variable-value-pairs> <body>)
– value of <body> becomes value of letvalue of <body> becomes value of let
Using LetUsing Let
(defun power (M N)(defun power (M N)
(let ((result 1))(let ((result 1))
(dotimes (i N result) (setf result (* M (dotimes (i N result) (setf result (* M result))))result))))
result now local – no complicationsresult now local – no complications Note: ((result 1))Note: ((result 1))
– listlist of variable-value pairs of variable-value pairs– each pair in its own listeach pair in its own list
Let with Multiple VariablesLet with Multiple Variables
Can use as many as you likeCan use as many as you like(defun correlation (X Y)(defun correlation (X Y)
(let ((N (length X))(let ((N (length X))(Sx (sum-list X))(Sx (sum-list X))(Sy (sum-list Y))(Sy (sum-list Y))(Sxy (dot-product X Y))(Sxy (dot-product X Y))(Sxx (sum-of-squares X))(Sxx (sum-of-squares X))(Syy (sum-of-squares Y)))(Syy (sum-of-squares Y)))
(/ (– (* N Sxy) (* Sx Sy)) (* (/ (– (* N Sxy) (* Sx Sy)) (* ……))))))))))
ExerciseExercise
Rewrite factorial and sum-to-N using letsRewrite factorial and sum-to-N using lets(defun factorial (N)(defun factorial (N)
(setf fact 1)(setf fact 1)
(dotimes (i N fact) (setf fact (* (+ i 1) fact))))(dotimes (i N fact) (setf fact (* (+ i 1) fact))))
(defun sum-to-N (N)(defun sum-to-N (N)
(setf sum 0)(setf sum 0)
(dotimes (i (+ N 1) sum) (setf sum (+ sum i))))(dotimes (i (+ N 1) sum) (setf sum (+ sum i))))
Let Works in ParallelLet Works in Parallel
All assignments are done “at the same time”All assignments are done “at the same time”– can’t use the value of one to set anothercan’t use the value of one to set another
> > (let ((x 5) (y (+ x 10))) (let ((x 5) (y (+ x 10))) ……))
ERROR – unbound variable XERROR – unbound variable X Won’t get an error if x Won’t get an error if x isis defined defined
– you’ll just get the you’ll just get the otherother value of x value of x– (let ((x 5) (y (+ x 10))) (+ x y))(let ((x 5) (y (+ x 10))) (+ x y)) => 796 (!!!) => 796 (!!!)
“other” X was 781
Let* Works in SerialLet* Works in Serial
In case you want to set one value based on In case you want to set one value based on anotheranother
> > (let* ((x 5) (y (+ x 10))) (+ x y))(let* ((x 5) (y (+ x 10))) (+ x y))
2020 X is already a local variable by the time let* X is already a local variable by the time let*
gets to itgets to it
DoListDoList
DoList allows iteration over listsDoList allows iteration over lists– do something for each element of a listdo something for each element of a list– also usually with side-effectsalso usually with side-effects
(dolist (<var> <list> <result>) <body>)(dolist (<var> <list> <result>) <body>)– <var> set to each element of <list> in turn<var> set to each element of <list> in turn– <body> evaluated for each value<body> evaluated for each value– <result> evaluated & returned<result> evaluated & returned
DoList ExampleDoList Example
(do-reverse ‘(1 2 3 4 5)) => (5 4 3 2 1)(do-reverse ‘(1 2 3 4 5)) => (5 4 3 2 1)(defun do-reverse (L)(defun do-reverse (L)
(let ((rev ()))(let ((rev ()))
(dolist (e L rev) (setf rev (cons e rev)))))(dolist (e L rev) (setf rev (cons e rev))))) Elements added to front of revElements added to front of rev
– rev = (), (cons 1 rev) => (1)rev = (), (cons 1 rev) => (1)– rev = (1), (cons 2 rev) => (2 1)rev = (1), (cons 2 rev) => (2 1)
Sum-List Using DoListSum-List Using DoList
> > (defun sum-list (L)(defun sum-list (L)(let ((sum 0))(let ((sum 0))
(dolist (e L sum) (setf sum (+ sum e)))))(dolist (e L sum) (setf sum (+ sum e)))))
> > (sum-list ‘(4 7 15))(sum-list ‘(4 7 15))sum sum 0 0
e e 4, sum 4, sum (+ 0 4) => 4 (+ 0 4) => 4e e 7, sum 7, sum (+ 4 7) => 11 (+ 4 7) => 11e e 15, sum 15, sum (+ 11 15) => 26 (+ 11 15) => 26
=> sum => 26=> sum => 26
ExerciseExercise
Write the function do-intersect, to calculate Write the function do-intersect, to calculate the intersection of two lists using let and the intersection of two lists using let and dolistdolist
> > (do-intersect ‘(1 3 5 7 9) ‘(3 6 9 12))(do-intersect ‘(1 3 5 7 9) ‘(3 6 9 12))
(9 3)(9 3)
SolutionSolution
Iterate thru first listIterate thru first list– if current element is in second list, add it to the if current element is in second list, add it to the
intersectionintersection– intersection should have started as emptyintersection should have started as empty
(defun do-intersection (L1 L2)(defun do-intersection (L1 L2)(let ((inter ()))(let ((inter ()))
(dolist (e L1 inter)(dolist (e L1 inter)(when (member e L2) (push e (when (member e L2) (push e
inter)))))inter)))))
Next TimeNext Time
ApplicationsApplications– chapters 24 & 26chapters 24 & 26