[parenscript-devel] New patch that adds real lexical scoping and maybe breaks your code

Vladimir Sedach vsedach at gmail.com
Fri May 15 00:48:13 UTC 2009


The advantages of this approach outweigh the disadvantages by such a
wide margin that there's no question in my mind. It's also not very
hard to optimize away the renaming if it does not need to be done
(which I guess puts the burden of proof on me). I just pushed a patch
that does not do gensym renaming if the variable in question has not
been bound in any enclosing lexical context, which deals with the
majority of the use cases of let.

Another heuristic that could be applied is to see if the variable is
referenced in any statements that execute after the binding and are
not captured by any closures in their lexical context, but that
requires a lot more hairy analysis because of things like scoping in
'for' loops. To be clear, this scenario most commonly occurs in code
like:

(defun foo (x)
  (let ((x (do-something x)))
    body))

Given the amount of hairy code vs potential readability improvement
('x1' vs 'x') I'm not sure this case is common enough to be worth
addressing.

Vladimir


On Wed, May 6, 2009 at 1:54 PM, Daniel Gackle <danielgackle at gmail.com> wrote:
> Whoa. I've just had a chance to look at this lexical scoping business. This
> is a major change, and needs a vigorous discussion. I'm not convinced that
> the benefits outweigh the costs.
>
> All local variables in our JS are now mangled by having a gensym-style
> suffix added to them. This considerably degrades the readability of the JS.
> One of the PS design goals has always been to balance nice abstractions at
> the source level with readability, ease of debugging, and efficiency in the
> generated code. This is a must-have because PS is not a compiler where you
> can just forget about the object code; those of us using PS on real projects
> have our hands immersed in the generated JS every day. I spend a great deal
> of time in Firebug, debugging and tracing and testing our code in the
> browser, and anything that degrades readability is a real drag.
>
> Against that cost, what is the benefit? I agree that it is a cool hack that
> gets lexical scoping into PS without resorting to nasty things like try
> blocks or nested lambdas. But I don't think that's a sufficient argument for
> putting it into PS. What's the practical benefit? Has anyone expressed a
> need for this feature? We've written many thousands of lines of PS code and
> not run into a need for it that I can recall.
>
> One option that won't work for us is to replace all usages of LET with VAR.
> A lot of our code is written in a subset of CL that is also emitted as PS.
> We can't throw out LET from that code. I suppose I could redefine PS's LET
> to just prepend a bunch of VAR statements to the block. It would be an
> unfortunate workaround, though.
>
> I'm not saying I'm adamantly opposed to this change, just that it's a major
> one that has some drawbacks. I think it ought to be discussed and debated.
> The pros and cons are not all obvious, and need to be flushed out.
>
> I'll post separately about a bug that seems to have been introduced. If that
> bug (and a few others) can be fixed, I'm willing to give this latest PS a
> try for a few weeks, as long as there's an alternative (short of regressing
> to an old version) to fall back on.
>
> Dan
>
>
>
>
>
>
> This is a major change. I think there needs to be a vigorous discussion
> about it. I'm not at all convinced that the benefits outweigh the costs, and
>
> mangling, debugging, readability
> obfuscation/minification
>
>
> On Sun, May 3, 2009 at 3:40 PM, Vladimir Sedach <vsedach at gmail.com> wrote:
>>
>> Hi,
>>
>> I just pushed a patch into the repository that may break existing
>> code. Here is the patch description:
>>
>>    Implemented LET and LET* by variable renaming, which provides the
>>    correct scoping semantics, and simplifies both the producing and the
>>    produced code.
>>
>>    Removed the "." and "[]" name-mangling conventions from
>>    symbol-to-js-string. Any code that uses symbols such as "foo.bar[baz]"
>>    will now issue a warning, and needs to be rewritten to use standard
>>    Lisp accessors. This is needed for variable renaming to work, and is
>>    an extension of the patch that eliminated the ".method" method-calling
>>    convention.
>>
>>    Thanks to Daniel Gackle and Dough Hoyte for opening my eyes to this
>>    technique, which was right in front of me all along.
>>
>> This is a win-win situation for everyone involved (yes, even if it
>> breaks your code, think of it as an opportunity for refactoring).
>>
>> With this patch Parenscript is finally rid of the evil symbol-abuse
>> conventions, which IMO is the only thing from the original design of
>> Parenscript that can in retrospect be called a mistake.
>>
>> Let me know what you guys think.
>>
>> Thank you,
>> Vladimir
>>
>> _______________________________________________
>> 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