I'm open to what you're saying, and I think that optimizing away renaming when it doesn't need to be done would go a long way toward reconciling the tradeoff. I'll have more suggestions once we've actually started using the release with lexical scoping (can't do it yet because of that symbol-macro bug I reported).<br>
<br>Dan<br><br><br><div class="gmail_quote">On Thu, May 14, 2009 at 6:48 PM, Vladimir Sedach <span dir="ltr"><<a href="mailto:vsedach@gmail.com">vsedach@gmail.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="border-left: 1px solid rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;">
The advantages of this approach outweigh the disadvantages by such a<br>
wide margin that there's no question in my mind. It's also not very<br>
hard to optimize away the renaming if it does not need to be done<br>
(which I guess puts the burden of proof on me). I just pushed a patch<br>
that does not do gensym renaming if the variable in question has not<br>
been bound in any enclosing lexical context, which deals with the<br>
majority of the use cases of let.<br>
<br>
Another heuristic that could be applied is to see if the variable is<br>
referenced in any statements that execute after the binding and are<br>
not captured by any closures in their lexical context, but that<br>
requires a lot more hairy analysis because of things like scoping in<br>
'for' loops. To be clear, this scenario most commonly occurs in code<br>
like:<br>
<br>
(defun foo (x)<br>
(let ((x (do-something x)))<br>
body))<br>
<br>
Given the amount of hairy code vs potential readability improvement<br>
('x1' vs 'x') I'm not sure this case is common enough to be worth<br>
addressing.<br>
<font color="#888888"><br>
Vladimir<br>
</font><div><div></div><div class="h5"><br>
<br>
On Wed, May 6, 2009 at 1:54 PM, Daniel Gackle <<a href="mailto:danielgackle@gmail.com">danielgackle@gmail.com</a>> wrote:<br>
> Whoa. I've just had a chance to look at this lexical scoping business. This<br>
> is a major change, and needs a vigorous discussion. I'm not convinced that<br>
> the benefits outweigh the costs.<br>
><br>
> All local variables in our JS are now mangled by having a gensym-style<br>
> suffix added to them. This considerably degrades the readability of the JS.<br>
> One of the PS design goals has always been to balance nice abstractions at<br>
> the source level with readability, ease of debugging, and efficiency in the<br>
> generated code. This is a must-have because PS is not a compiler where you<br>
> can just forget about the object code; those of us using PS on real projects<br>
> have our hands immersed in the generated JS every day. I spend a great deal<br>
> of time in Firebug, debugging and tracing and testing our code in the<br>
> browser, and anything that degrades readability is a real drag.<br>
><br>
> Against that cost, what is the benefit? I agree that it is a cool hack that<br>
> gets lexical scoping into PS without resorting to nasty things like try<br>
> blocks or nested lambdas. But I don't think that's a sufficient argument for<br>
> putting it into PS. What's the practical benefit? Has anyone expressed a<br>
> need for this feature? We've written many thousands of lines of PS code and<br>
> not run into a need for it that I can recall.<br>
><br>
> One option that won't work for us is to replace all usages of LET with VAR.<br>
> A lot of our code is written in a subset of CL that is also emitted as PS.<br>
> We can't throw out LET from that code. I suppose I could redefine PS's LET<br>
> to just prepend a bunch of VAR statements to the block. It would be an<br>
> unfortunate workaround, though.<br>
><br>
> I'm not saying I'm adamantly opposed to this change, just that it's a major<br>
> one that has some drawbacks. I think it ought to be discussed and debated.<br>
> The pros and cons are not all obvious, and need to be flushed out.<br>
><br>
> I'll post separately about a bug that seems to have been introduced. If that<br>
> bug (and a few others) can be fixed, I'm willing to give this latest PS a<br>
> try for a few weeks, as long as there's an alternative (short of regressing<br>
> to an old version) to fall back on.<br>
><br>
> Dan<br>
><br>
><br>
><br>
><br>
><br>
><br>
> This is a major change. I think there needs to be a vigorous discussion<br>
> about it. I'm not at all convinced that the benefits outweigh the costs, and<br>
><br>
> mangling, debugging, readability<br>
> obfuscation/minification<br>
><br>
><br>
> On Sun, May 3, 2009 at 3:40 PM, Vladimir Sedach <<a href="mailto:vsedach@gmail.com">vsedach@gmail.com</a>> wrote:<br>
>><br>
>> Hi,<br>
>><br>
>> I just pushed a patch into the repository that may break existing<br>
>> code. Here is the patch description:<br>
>><br>
>> Implemented LET and LET* by variable renaming, which provides the<br>
>> correct scoping semantics, and simplifies both the producing and the<br>
>> produced code.<br>
>><br>
>> Removed the "." and "[]" name-mangling conventions from<br>
>> symbol-to-js-string. Any code that uses symbols such as "foo.bar[baz]"<br>
>> will now issue a warning, and needs to be rewritten to use standard<br>
>> Lisp accessors. This is needed for variable renaming to work, and is<br>
>> an extension of the patch that eliminated the ".method" method-calling<br>
>> convention.<br>
>><br>
>> Thanks to Daniel Gackle and Dough Hoyte for opening my eyes to this<br>
>> technique, which was right in front of me all along.<br>
>><br>
>> This is a win-win situation for everyone involved (yes, even if it<br>
>> breaks your code, think of it as an opportunity for refactoring).<br>
>><br>
>> With this patch Parenscript is finally rid of the evil symbol-abuse<br>
>> conventions, which IMO is the only thing from the original design of<br>
>> Parenscript that can in retrospect be called a mistake.<br>
>><br>
>> Let me know what you guys think.<br>
>><br>
>> Thank you,<br>
>> Vladimir<br>
>><br>
>> _______________________________________________<br>
>> parenscript-devel mailing list<br>
>> <a href="mailto:parenscript-devel@common-lisp.net">parenscript-devel@common-lisp.net</a><br>
>> <a href="http://common-lisp.net/cgi-bin/mailman/listinfo/parenscript-devel" target="_blank">http://common-lisp.net/cgi-bin/mailman/listinfo/parenscript-devel</a><br>
><br>
><br>
> _______________________________________________<br>
> parenscript-devel mailing list<br>
> <a href="mailto:parenscript-devel@common-lisp.net">parenscript-devel@common-lisp.net</a><br>
> <a href="http://common-lisp.net/cgi-bin/mailman/listinfo/parenscript-devel" target="_blank">http://common-lisp.net/cgi-bin/mailman/listinfo/parenscript-devel</a><br>
><br>
><br>
<br>
_______________________________________________<br>
parenscript-devel mailing list<br>
<a href="mailto:parenscript-devel@common-lisp.net">parenscript-devel@common-lisp.net</a><br>
<a href="http://common-lisp.net/cgi-bin/mailman/listinfo/parenscript-devel" target="_blank">http://common-lisp.net/cgi-bin/mailman/listinfo/parenscript-devel</a><br>
</div></div></blockquote></div><br>