What you describe would be a good compromise, and I'm fine with using let* instead of let. However, let* doesn't work as you describe in the current darcs version of PS:
(ps (defun blah () (let* ((x 3)) (return x))))
=>
"function blah() { var tempstackvar26357; try { tempstackvar26357 = x; x = 3; return x; } finally { x = tempstackvar26357; delete tempstackvar26357; }; };"
What I need here, of course, is:
"function blah() { var x = 3; return x; };"
Is the latter what you intend let* to produce? If so, that would work for me.
By the way, I'm not opposed to adding new abstractions to PS - there are a lot of great things that can be added. A good example is the work Red did to support &optional and &key parameters. That was a nice hack because the JS semantics (i.e. its arguments array) are close enough to Lisp to bridge the gap. (Even so, there are a few functions where I don't want to pay the runtime price for that abstraction).
Another promising area might be CL's sequence functions. I bet these would map fairly well to JS arrays.
On the other hand, the world of cons/car/cdr doesn't map well. I'm dealing with this right now because we have a sizeable chunk of CL code that also needs to run in the browser. I'm hacking a rudimentary compiler to generate JS for it (basically a bunch of local ps-macros to coax PS into compiling the CL code). What I don't want to do is implement Lisp conses in JS. That's an area, I think, where the gap is too huge to be bridged well.
Dan
On Sun, Aug 17, 2008 at 4:26 AM, Travis Cross tc@travislists.com wrote:
Daniel Gackle wrote:
First, the semantics of let have changed to be more Lisp-like. Is that correct? This causes some practical problems. In much of our app, performance is critical and we can't afford to have temporary variable reassignment, try/finally, and delete magic going on under the hood. What we need is plain-old, naked Javascript variable assignment - the simplest generated code possible. As of 20071104, that's exactly what PS generated for let. Now, it generates code that's considerably more complex, which we mostly can't use.
My questions are: (1) Does anyone need Lispy let, or can we just take it out and revert to the simpler let? (2) If it really is needed, can we come up with an easy way to offer the user their choice of assignment semantics (perhaps a special variable)?
The semantics of LET (and DO) did change to be more lisp-like. At the same time, LET* and DO* were introduced for access to more native JS semantics.
The idea is that PS feels pretty close to lisp in other ways, so the expected semantics of CL:LET should be broken as little as possible when there already exists a CL construct that better matches native JS semantics: LET*. When writing PS, I use LET* most of the time for the same reasons you outlined above. I still prefer having that * there as a visual reminder of what is really going on.
Is this change still going to be a huge issue for you now that you know we introduced LET*? It seems that if you want LET*-like semantics everywhere in your existing code, you just need to search/replace all of your LETs into LET*s (or, alternatively, locally bind PS:LET to PS:LET*).
Cheers,
-- Travis