I'm stuck on a particular example used in the above mentioned book. The relevant code can be found here.
Code: Select all
; Closure captures assigned variable -- probably wrong
? (let ((fns ()))
(dotimes (i 3)
(push #'(lambda () i) fns))
(mapcar #'funcall fns))
(3 3 3)
- 1. the 'let encloses all the variables within its scope: the loop variable 'i and the empty list 'fns.
2. 'dotimes simply repeats the enclosed functions '3 times, (zero indexed so... (0 1 2)).
3. 'push is cons'ing the lambda function onto 'fns (nice)
4. the list (3 3 3) is undesired and is the effect of the closure created by the 'let over the iteration variable 'i. WHY?!
Code: Select all
(step (let ((fn ()))(dotimes (i 3)(push #'(lambda()i)fn))))
Code: Select all
step 9 --> (CONS #'(LAMBDA NIL I) FN)
Step 9 [29]> :s
step 10 --> #'(LAMBDA NIL I)
Step 10 [30]> :s
step 10 ==> value: #<FUNCTION :LAMBDA NIL I>
step 10 --> FN
Step 10 [31]> :s
step 10 ==> value: (#<FUNCTION :LAMBDA NIL I>)
step 9 ==> value: (#<FUNCTION :LAMBDA NIL I> #<FUNCTION :LAMBDA NIL I>)
step 8 ==> value: (#<FUNCTION :LAMBDA NIL I> #<FUNCTION :LAMBDA NIL I>)
step 7 ==> value: (#<FUNCTION :LAMBDA NIL I> #<FUNCTION :LAMBDA NIL I>)
step 7 --> (PSETQ I (1+ I))
Step 7 [32]> :s
step 8 --> (1+ I)
Step 8 [33]> :s
step 9 --> I
Step 9 [34]> :s
step 9 ==> value: 1
step 8 ==> value: 2
step 7 ==> value: NIL
step 7 --> (GO #:LOOP-3858)
Step 7 [35]> :s
step 7 --> (IF (>= I 3) (GO #:END-3859))
Step 7 [36]> :s
step 8 --> (>= I 3)
Step 8 [37]> :s
step 9 --> I
Step 9 [38]> :s
step 9 ==> value: 2
step 9 --> 3
Step 9 [39]> :s
step 9 ==> value: 3
step 8 ==> value: NIL
step 7 ==> value: NIL
step 7 --> (PUSH #'(LAMBDA NIL I) FN)