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

Vladimir Sedach vsedach at gmail.com
Sat Dec 17 20:44:35 UTC 2011


I pushed fixes for both problems 1 and 2. Try them out.

As a consequence, most Parenscript expressions should also now "work"
(return a value, and not introduce spurious global variables) at the
top-level, which should make it much easier to do Parenscript REPLs.

Vladimir

On Mon, Dec 12, 2011 at 7:16 PM, Vladimir Sedach <vsedach at gmail.com> wrote:
> 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