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 <[email protected]> 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 <[email protected]> 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 <[email protected]> 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 <[email protected]> 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 <[email protected]> >>>> 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 <[email protected]> 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 >>>> >> [email protected] >>>> >> http://lists.common-lisp.net/cgi-bin/mailman/listinfo/parenscript-devel >>>> > >>>> > >>>> > _______________________________________________ >>>> > parenscript-devel mailing list >>>> > [email protected] >>>> > http://lists.common-lisp.net/cgi-bin/mailman/listinfo/parenscript-devel >>>> > >>>> > >>>> >>>> _______________________________________________ >>>> parenscript-devel mailing list >>>> [email protected] >>>> http://lists.common-lisp.net/cgi-bin/mailman/listinfo/parenscript-devel >>> >>> >>> _______________________________________________ >>> parenscript-devel mailing list >>> [email protected] >>> http://lists.common-lisp.net/cgi-bin/mailman/listinfo/parenscript-devel >>> >>> >> >> _______________________________________________ >> parenscript-devel mailing list >> [email protected] >> http://lists.common-lisp.net/cgi-bin/mailman/listinfo/parenscript-devel _______________________________________________ parenscript-devel mailing list [email protected] http://lists.common-lisp.net/cgi-bin/mailman/listinfo/parenscript-devel
