On Thu, Dec 3, 2009 at 1:41 PM, Daniel Gackle danielgackle@gmail.com wrote:
I've now had a chance to systematically look at how our code fares under PS's implicit return. Thanks to Scott for being the guinea pig for the rest of us. I like it! I do have a few questions/issues. I'll send them in separate emails, I guess.
PS now tries to insert a default "return null;" statement in functions that would formerly have returned nothing, i.e. whose return values would have been undefined. I am not convinced that this buys us much. We've always treated NULL and UNDEFINED as conveying the same information when returning from a function. I recognize not everyone would share this interpretation.
The trouble with explicit "return null" is that you end up with things like the following example taken from our code (stripped-down for brevity):
(defun blep (ss x y) (when foo? (awhen (bar) (destructuring-bind (c r) it (when (!null c r) (awhen (baz) (when (blah it) (unless (blee) t))))))))
=>
function blep(ss, x, y) { if (foowhat) { var it = bar(); if (it != null && it !== false) { var c = it[0]; var r = it[1]; if (c != null && r != null) { var it27537 = baz(); if (it27537 != null && it27537 !== false) { if (blah(it27537)) { if (!blee()) { return true; } else { return null; }; } else { return null; }; } else { return null; }; } else { return null; }; } else { return null; }; } else { return null; }; };
For this specific example it's more a matter of generating reasonable code. There is a better way to represent this function, even when implicitly returning null:
function blep(ss, x, y) { var expr = null; if (foowhat) { var it = bar(); if (it != null && it !== false) { var c = it[0]; var r = it[1]; if (c != null && r != null) { var it27537 = baz(); if (it27537 != null && it27537 !== false) { if (blah(it27537)) { if (!blee()) { expr = true; } } } } } } return expr; };
Now if I am not mistaken, Parenscript cannot make (or fake) an expression from any old Parenscript form. In my mind this is a shortcoming of Parenscript, not something we should embrace because Javascript distinguishes between statements and expressions. If I am wrong, then I'd be glad to hear about it!
If we had a 100% working parenscript-form => javascript expression implementation, then implementing implicit returning would be simpler and this code generation. I have not seen the implicit return code, but this behavior may require more extensive semantic analysis than Parenscript currently supports.
I wish PS would avoid generating all those "return null"s when the only thing we need is the "return true".
Note also that PS is not *always* returning null; there are cases where the old undefined behavior still exists:
(ps (defun foo () (dolist (a b) (blah a)))) => "function foo() { for (var a = null, _js_idx27540 = 0; _js_idx27540 < b.length; _js_idx27540 += 1) { a = b[_js_idx27540]; blah(a); }; };"
Personally, I think this is fine and would rather see all functions behave this way. That is, if I put a NIL in a tail position in my code, I should get "return null" and otherwise no explicit return in JS. We can't factor the null vs. undefined distinction out of PS altogether; it's too engrained in JS. Anyway this issue is, to my mind, distinct from the implicit return feature as such.
For most cases it will not make any difference. If it is important to the application, you can always explicitly return ps:undefined or nil.
Red
What am I missing?
Daniel
parenscript-devel mailing list parenscript-devel@common-lisp.net http://common-lisp.net/cgi-bin/mailman/listinfo/parenscript-devel