<div>When a closure is created inside a loop, PS wraps the closed-over</div><div>variables using a JS WITH statement to ensure that each closure will get</div><div>the values that existed at the time it was created. Here's an example</div>
<div>from Vladimir's email to the list from Jan 30, 2011:</div><div><br></div><div> (let ((foo (make-array 3)))</div><div> (dotimes (i 3)</div><div> (setf (aref foo i) (lambda () i)))</div><div> (funcall (@ console log) (funcall (aref foo 0)))</div>
<div> (funcall (@ console log) (funcall (aref foo 1)))</div><div> (funcall (@ console log) (funcall (aref foo 2))))</div><div><br></div><div>This correctly prints 0,1,2 to the console. If PS didn't do this extra</div>
<div>work and relied on JS scoping, the output would be 3,3,3 which is</div><div>obviously (or at least arguably) incorrect.</div><div><br></div><div>But this doesn't happen for variables declared prior to the loop form.</div>
<div>Here is the above example written to use WHILE rather than DOTIMES:</div><div><br></div><div> (let ((foo (make-array 3))</div><div> (i 0))</div><div> (while (< i 3)</div><div> (setf (aref foo i) (lambda () i))</div>
<div> (incf i))</div><div> (funcall (@ console log) (funcall (aref foo 0)))</div><div> (funcall (@ console log) (funcall (aref foo 1)))</div><div> (funcall (@ console log) (funcall (aref foo 2))))</div>
<div>
<br></div><div><div>It prints 3,3,3. Of course, probably no one would use WHILE to write</div><div>this particular loop, but it's easy to see how one might run in to the</div><div>problem. In particular, the PS LOOP macro generates WHILE forms for</div>
<div>many standard kinds of loop. That is how I ran across this issue: I</div><div>have a LOOP form that builds a table of closures for asynchronous</div><div>callback in a Node.js program and by the time these closures are</div>
<div>called back, they no longer have their expected data - for exactly the</div><div>same reason as the above example prints 3,3,3.</div></div><div><br></div><div>My first question is: is this a bug? That is, if it's incorrect for the</div>
<div>first loop to print 3,3,3, is it also incorrect for the second loop to</div><div>do so?</div><div><br></div><div>Daniel</div><div><br></div>