<div>Thanks. I noticed the same thing about CL, but wasn't clear on the</div><div>principle.  Now I think I understand. The salient question is: was the</div><div>variable declared inside the loop? If it was, there's an implicit</div>

<div>request to get a new binding each time the loop executes. If it</div><div>wasn't, all closures over the variable will share the same binding.</div><div><br></div><br><div class="gmail_quote">On Fri, Apr 6, 2012 at 5:52 PM, Vladimir Sedach <span dir="ltr"><<a href="mailto:vsedach@gmail.com">vsedach@gmail.com</a>></span> wrote:<br>

<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">That's the correct behavior because you're closing over the same<br>
binding of i in all iterations. This equivalent CL code:<br>
<div class="im"><br>
(let ((foo (make-array 3))<br>
               (i 0))<br>
</div>           (loop while (< i 3) do<br>
<div class="im">             (setf (aref foo i) (lambda () i))<br>
             (incf i))<br>
</div>           (funcall #'princ (funcall (aref foo 0)))<br>
           (funcall #'princ (funcall (aref foo 1)))<br>
           (funcall #'princ (funcall (aref foo 2))))<br>
<br>
Also does 3 3 3<br>
<br>
Vladimir<br>
<div><div></div><div class="h5"><br>
On Thu, Apr 5, 2012 at 7:20 PM, Daniel Gackle <<a href="mailto:danielgackle@gmail.com">danielgackle@gmail.com</a>> wrote:<br>
> When a closure is created inside a loop, PS wraps the closed-over<br>
> variables using a JS WITH statement to ensure that each closure will get<br>
> the values that existed at the time it was created. Here's an example<br>
> from Vladimir's email to the list from Jan 30, 2011:<br>
><br>
>    (let ((foo (make-array 3)))<br>
>      (dotimes (i 3)<br>
>        (setf (aref foo i) (lambda () i)))<br>
>      (funcall (@ console log) (funcall (aref foo 0)))<br>
>      (funcall (@ console log) (funcall (aref foo 1)))<br>
>      (funcall (@ console log) (funcall (aref foo 2))))<br>
><br>
> This correctly prints 0,1,2 to the console. If PS didn't do this extra<br>
> work and relied on JS scoping, the output would be 3,3,3 which is<br>
> obviously (or at least arguably) incorrect.<br>
><br>
> But this doesn't happen for variables declared prior to the loop form.<br>
> Here is the above example written to use WHILE rather than DOTIMES:<br>
><br>
>    (let ((foo (make-array 3))<br>
>          (i 0))<br>
>      (while (< i 3)<br>
>        (setf (aref foo i) (lambda () i))<br>
>        (incf i))<br>
>      (funcall (@ console log) (funcall (aref foo 0)))<br>
>      (funcall (@ console log) (funcall (aref foo 1)))<br>
>      (funcall (@ console log) (funcall (aref foo 2))))<br>
><br>
> It prints 3,3,3. Of course, probably no one would use WHILE to write<br>
> this particular loop, but it's easy to see how one might run in to the<br>
> problem. In particular, the PS LOOP macro generates WHILE forms for<br>
> many standard kinds of loop. That is how I ran across this issue: I<br>
> have a LOOP form that builds a table of closures for asynchronous<br>
> callback in a Node.js program and by the time these closures are<br>
> called back, they no longer have their expected data - for exactly the<br>
> same reason as the above example prints 3,3,3.<br>
><br>
> My first question is: is this a bug? That is, if it's incorrect for the<br>
> first loop to print 3,3,3, is it also incorrect for the second loop to<br>
> do so?<br>
><br>
> Daniel<br>
><br>
><br>
</div></div>> _______________________________________________<br>
> parenscript-devel mailing list<br>
> <a href="mailto:parenscript-devel@common-lisp.net">parenscript-devel@common-lisp.net</a><br>
> <a href="http://lists.common-lisp.net/cgi-bin/mailman/listinfo/parenscript-devel" target="_blank">http://lists.common-lisp.net/cgi-bin/mailman/listinfo/parenscript-devel</a><br>
><br>
<br>
_______________________________________________<br>
parenscript-devel mailing list<br>
<a href="mailto:parenscript-devel@common-lisp.net">parenscript-devel@common-lisp.net</a><br>
<a href="http://lists.common-lisp.net/cgi-bin/mailman/listinfo/parenscript-devel" target="_blank">http://lists.common-lisp.net/cgi-bin/mailman/listinfo/parenscript-devel</a><br>
</blockquote></div><br>