[parenscript-devel] "let over lambda" seems buggy

Vladimir Sedach vsedach at gmail.com
Tue Dec 13 00:16:34 UTC 2011


I see two bugs in Parenscript here:

1. Parenscript should wrap forms like (create "fn" (let ((x)) (lambda
() x))) compiled at the toplevel in a lambda to prevent capture of
global variables. So the code should look like:

(ps (create "fn" (let ((x)) (lambda () x))))
=>
"(function () {
    var x;
    return { 'fn' : (x = null, function () {
        return x;
    }) };
})();"

2. The other bug I see is that even if you wrap the create in a lambda
right now, the same variable x will be captured:

(ps (lambda () (create "fn"   (let ((x)) (lambda () x))
                                "fn2" (let ((x 2)) (lambda () x)))))
=>

"(function () {
    var x;
    return { 'fn' : (x = null, function () {
        return x;
    }), 'fn2' : (x = 2, function () {
        return x;
    }) };
});"

This is obviously wrong behavior. I'm going to work on some fixes.

Vladimir

On Thu, Oct 13, 2011 at 3:25 AM, Canhua <dreameration at gmail.com> wrote:
> Thank you for your suggestion. I should work. And I may also use a
> variable name for "x" that isn't possible to conflict (use gensym).
> So, yes, there are ways to work around this issue. But I learnt that
> "let over lambda" in parenscript is different from that in common
> lisp. Is that right?
>
> The reason why I want need this is that I have to pass the whole
> object as argument to a library function. Many js libraries seem like
> to use object as configuration argument.
>
> On Thu, Oct 13, 2011 at 3:13 PM, Vsevolod Dyomkin <vseloved at gmail.com> wrote:
>> I suggest, that you first consider, how would you do that in JS. You'll need
>> to wrap that in functions:
>> {
>> 'fn_1' : (function () {
>>               var x = 1;
>>               return function () { return x; } }) (),
>> 'fn_2' : (function () {
>>               var x = 2;
>>               return function () { return x; } }) ()
>> }
>> Now let's think, how this can be done in Parenscript?..
>> PS. But the most important question is: why do you need to create a single
>> function, that closes over a "private" variable, as part of an object? Isn't
>> it equivalent to just coding the value of the variable inside the function?
>> vsevolod
>>
>>
>> On Thu, Oct 13, 2011 at 10:05 AM, Canhua <dreameration at gmail.com> wrote:
>>>
>>> actually what I want to achieve is something like this:
>>> (create "fn_1" (let ((x))
>>>                         #'(lambda ()
>>>                             x))
>>>           "fn_2" (let ((x))
>>>                         #'(lambda ()
>>>                             x)))
>>> and I expected these two "x" are lexical-scope separate and so
>>> independent from each other.
>>> However the compiled js code doesn't work as I expected.
>>>
>>>
>>> On Thu, Oct 13, 2011 at 2:51 PM, Vsevolod Dyomkin <vseloved at gmail.com>
>>> wrote:
>>> > Hi
>>> > Actually the above code is correct.
>>> > You can also use:
>>> > - either
>>> > (let (x)
>>> >     (create "fn" (lambda () x)))
>>> > - or
>>> > (create "x" nil
>>> >            "fn" (lambda () x)))
>>> > depending on the JS semantics you want to get.
>>> > vsevolod
>>> >
>>> >
>>> > On Thu, Oct 13, 2011 at 8:40 AM, Canhua <dreameration at gmail.com> wrote:
>>> >>
>>> >> hi, all, I found that
>>> >>     (create "fn" (let ((x))
>>> >>                        (lambda () x)))
>>> >>
>>> >> compiles to
>>> >>     { 'fn' : (x = null, function () {
>>> >>      return x;
>>> >>     }) }
>>> >>
>>> >> wherein the variable x may conflict with a variable with the same name
>>> >> outside this code.
>>> >> How may avoid this? How may I achieve "let over lambda" closure effect
>>> >> as in common lisp?
>>> >>
>>> >> Thanks.
>>> >>
>>> >> _______________________________________________
>>> >> parenscript-devel mailing list
>>> >> parenscript-devel at common-lisp.net
>>> >> http://lists.common-lisp.net/cgi-bin/mailman/listinfo/parenscript-devel
>>> >
>>> >
>>> > _______________________________________________
>>> > parenscript-devel mailing list
>>> > parenscript-devel at common-lisp.net
>>> > http://lists.common-lisp.net/cgi-bin/mailman/listinfo/parenscript-devel
>>> >
>>> >
>>>
>>> _______________________________________________
>>> parenscript-devel mailing list
>>> parenscript-devel at common-lisp.net
>>> http://lists.common-lisp.net/cgi-bin/mailman/listinfo/parenscript-devel
>>
>>
>> _______________________________________________
>> parenscript-devel mailing list
>> parenscript-devel at common-lisp.net
>> http://lists.common-lisp.net/cgi-bin/mailman/listinfo/parenscript-devel
>>
>>
>
> _______________________________________________
> parenscript-devel mailing list
> parenscript-devel at common-lisp.net
> http://lists.common-lisp.net/cgi-bin/mailman/listinfo/parenscript-devel




More information about the parenscript-devel mailing list