[parenscript-devel] Why is there a WITH clause in my loop?

Vladimir Sedach vsedach at gmail.com
Sun Jan 30 23:44:28 UTC 2011


The 'with' only happens if there's a lambda capturing the loop
variables. Consider this code:

(let ((foo (make-array 3)))
  (dotimes (i 3)
    (setf (aref foo i) (lambda () i)))
  (funcall (@ console log) (funcall (aref foo 0)))
  (funcall (@ console log) (funcall (aref foo 1)))
  (funcall (@ console log) (funcall (aref foo 2))))

With 'with':

var foo = new Array(3);
for (var i = 0; i < 3; i += 1) {
    with ({ i : i }) {
        foo[i] = function () {
            return i;
        };
    };
};
console.log(foo[0]());
console.log(foo[1]());
console.log(foo[2]());

=> 0 1 2

Without 'with':

var foo = new Array(3);
for (var i = 0; i < 3; i += 1) {
        foo[i] = function () {
            return i;
        };
};
console.log(foo[0]());
console.log(foo[1]());
console.log(foo[2]());

=> 3 3 3

Vladimir

2011/1/28 Daniel Gackle <danielgackle at gmail.com>:
> Specifically, I'm having a hard time seeing how this:
>   function blah(obj) {
>       for (var key in obj) {
>           with ({ x : null }) {
>               var x = [];
>               // do anything at all here...
> can ever be better than this:
>   function blah(obj) {
>       for (var key in obj) {
>           var x = [];
>           // do that thing here instead...
> What am I missing?
>
>
>
>
>
> 2011/1/28 Daniel Gackle <danielgackle at gmail.com>
>>
>> I'm running to this WITH clause in a number of places, but can't see
>> the (potential) bug you describe in any of them. Can you provide an
>> example of this bug (that necessitates the WITH)? I don't get it yet.
>> Daniel
>>
>> 2010/12/10 Vladimir Sedach <vsedach at gmail.com>
>>>
>>> The WITH clause is there to make sure that lambdas capture a fresh
>>> binding of loop-local variables per iteration (otherwise they'd all
>>> share the same binding which would get incremented on every loop
>>> iteration).
>>>
>>> I'm guessing the reason your code doesn't run across this bug is that
>>> the lambda that captures time gets called once per iteration and
>>> discarded.
>>>
>>> Vladimir
>>>
>>> 2010/12/7 Daniel Gackle <danielgackle at gmail.com>:
>>> > Here's a really strange one.
>>> > We have a form like the following. I've stripped it down for brevity,
>>> > so it
>>> > looks weird:
>>> > (loop :for time :from time1 :below time2 :do
>>> >   (when (foo
>>> >          (λ ()
>>> >            (bar
>>> >             (λ () (blah)) time))
>>> >          time)
>>> >     (break)))
>>> > It used to generate this:
>>> > for (var time = time1; time < time2; time += 1) {
>>> >     if (foo(function () {
>>> >         return barr(function () {
>>> >             return blah();
>>> >         }, time);
>>> >     }, time)) {
>>> >         break;
>>> >     };
>>> > };
>>> > But now it generates this:
>>> > for (var time = time1; time < time2; time += 1) {
>>> >     with ({ time : time }) {
>>> >         if (foo(function () {
>>> >             return bar(function () {
>>> >                 return blah();
>>> >             }, time);
>>> >         }, time)) {
>>> >             break;
>>> >         };
>>> >     };
>>> > };
>>> > That is one weird WITH clause in there! No doubt it has something
>>> > to do with lexical scoping magic going on under the hood. But
>>> > I definitely don't want it in a performance-critical loop.
>>> > Daniel
>>> > _______________________________________________
>>> > parenscript-devel mailing list
>>> > parenscript-devel at common-lisp.net
>>> > http://common-lisp.net/cgi-bin/mailman/listinfo/parenscript-devel
>>> >
>>> >
>>>
>>> _______________________________________________
>>> parenscript-devel mailing list
>>> parenscript-devel at common-lisp.net
>>> http://common-lisp.net/cgi-bin/mailman/listinfo/parenscript-devel
>>
>
>
> _______________________________________________
> parenscript-devel mailing list
> parenscript-devel at common-lisp.net
> http://common-lisp.net/cgi-bin/mailman/listinfo/parenscript-devel
>
>




More information about the parenscript-devel mailing list