[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