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@gmail.com wrote:
I see two bugs in Parenscript here:
- 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; }) }; })();"
- 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@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@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@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@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@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@common-lisp.net http://lists.common-lisp.net/cgi-bin/mailman/listinfo/parenscript-devel
parenscript-devel mailing list parenscript-devel@common-lisp.net http://lists.common-lisp.net/cgi-bin/mailman/listinfo/parenscript-devel
parenscript-devel mailing list parenscript-devel@common-lisp.net http://lists.common-lisp.net/cgi-bin/mailman/listinfo/parenscript-devel
parenscript-devel mailing list parenscript-devel@common-lisp.net http://lists.common-lisp.net/cgi-bin/mailman/listinfo/parenscript-devel
parenscript-devel mailing list parenscript-devel@common-lisp.net http://lists.common-lisp.net/cgi-bin/mailman/listinfo/parenscript-devel