The 'expressionize' function seems to be at the core of implicit returns. It seems to be a promising approach to morphing Javascript into an everything-is-an-expression language. Unfortunately right now it is poorly documented and not used everywhere it could be. Hopefully we can discuss where this feature is heading publicly and finish up expressionizing parenscript.
Right now LET does not seem to take advantage of expressionize the same way functions do. LET fails to turn TRY into an expression, while implicit return works. What would we need to do to add this?
(ps:ps (let ((x (ps:try xxx (:catch (x) 5)))) x)) "var x233 = try { xxx; } catch (x) { 5; }; x233;"
below works:
(ps:ps (lambda ()
(ps:try xxx (:catch (x) 5)))) "function () { try { return xxx; } catch (x) { return 5; }; };"
Thanks for the insights, Red
The 'expressionize' function seems to be at the core of implicit returns. It seems to be a promising approach to morphing Javascript into an everything-is-an-expression language.
Yes. After I wrote implicit return it became obvious that could be generalized into "expressionize."
Unfortunately right now it is poorly documented and not used everywhere it could be.
I'm pretty sure it also has some pretty big bugs. More importantly, I don't think it works as advertised if you try to use it in arbitrary places right now.
Hopefully we can discuss where this feature is heading publicly and finish up expressionizing parenscript.
Right now LET does not seem to take advantage of expressionize the same way functions do. LET fails to turn TRY into an expression, while implicit return works. What would we need to do to add this?
At first thought all the places where the Parenscript special forms need expressions are already annotated with the COMPILE-EXPRESSION function. So one possible way is to just expressionize all statements that end up getting compiled by COMPILE-EXPRESSION into lambdas that get called in-place. This is what most other Lisp to JS compilers seem to do. This would look like
(+ 1 (dolist ()...)) => (+ 1 (funcall (lambda () (var x) (dolist ()... finally x = _) (return x)))
If we're willing to tolerate Scheme calling convention (argument evaluation order is unspecified), this could be transformed into more idiomatic JS:
(+ 1 (dolist () ...)) =>
(var x) (dolist () ... finally x = _) (+ 1 x)
I think I brought up this idea (undefined argument evaluation order) before in relation to some other feature, but I can't find a mention of that now.
Vladimir
(ps:ps (let ((x (ps:try xxx (:catch (x) 5)))) x)) "var x233 = try { xxx; } catch (x) { 5; }; x233;"
below works:
(ps:ps (lambda ()
(ps:try xxx (:catch (x) 5)))) "function () { try { return xxx; } catch (x) { return 5; }; };"
Thanks for the insights, Red
parenscript-devel mailing list parenscript-devel@common-lisp.net http://common-lisp.net/cgi-bin/mailman/listinfo/parenscript-devel
Thanks for the reply.
On Thu, Aug 19, 2010 at 10:19 AM, Vladimir Sedach vsedach@gmail.com wrote:
The 'expressionize' function seems to be at the core of implicit returns. It seems to be a promising approach to morphing Javascript into an everything-is-an-expression language.
Yes. After I wrote implicit return it became obvious that could be generalized into "expressionize."
Unfortunately right now it is poorly documented and not used everywhere it could be.
I'm pretty sure it also has some pretty big bugs. More importantly, I don't think it works as advertised if you try to use it in arbitrary places right now.
Yes, though it's a good start and it's already gotten us working implicit return. It does work with only a few forms, because expressionize will do things like use the lambda passed into it multiple times. It also works with forms before they are compiled by the special-form transformers (i.e. you pass in Parenscript forms, not JS-as-sexps forms).
Hopefully we can discuss where this feature is heading publicly and finish up expressionizing parenscript.
Right now LET does not seem to take advantage of expressionize the same way functions do. LET fails to turn TRY into an expression, while implicit return works. What would we need to do to add this?
At first thought all the places where the Parenscript special forms need expressions are already annotated with the COMPILE-EXPRESSION function. So one possible way is to just expressionize all statements that end up getting compiled by COMPILE-EXPRESSION into lambdas that get called in-place. This is what most other Lisp to JS compilers seem to do. This would look like
(+ 1 (dolist ()...)) => (+ 1 (funcall (lambda () (var x) (dolist ()... finally x = _) (return x)))
If we're willing to tolerate Scheme calling convention (argument evaluation order is unspecified), this could be transformed into more idiomatic JS:
(+ 1 (dolist () ...)) =>
(var x) (dolist () ... finally x = _) (+ 1 x)
Indeed. I don't think it would be impossible to guarantee the evaluation order either, but it will take some thought. For example, forms like this:
(let ((x (+ (call-me-first) (try (unsafe) (:catch (e) "failure"))))) x)
Would need to compile to
var called_first = callMeFirst(); var result1; try { result1 = unsafe(); } catch (e) { result 1 = "failure"; } var x = called_first + result1;
I'm not really sure where the right place to implement this is. Perhaps we can implement a pseudo-expression special form. But I don't know in what stage of processing we would need to process expressions with pseudo-expressions. Any idea on how we could potentially implement this?
Another alternative is to introduce a pseudo-lambda special form, in which case it is necessary to code walk the generated code to check for things like 'arguments', 'this', return and break statements. I think this approach is quite doable, though it may require a better code walker than we have already.
I think I brought up this idea (undefined argument evaluation order) before in relation to some other feature, but I can't find a mention of that now.
Vladimir
Red
(ps:ps (let ((x (ps:try xxx (:catch (x) 5)))) x)) "var x233 = try { xxx; } catch (x) { 5; }; x233;"
below works:
(ps:ps (lambda ()
(ps:try xxx (:catch (x) 5)))) "function () { try { return xxx; } catch (x) { return 5; }; };"
Thanks for the insights, Red
parenscript-devel mailing list parenscript-devel@common-lisp.net http://common-lisp.net/cgi-bin/mailman/listinfo/parenscript-devel
parenscript-devel mailing list parenscript-devel@common-lisp.net http://common-lisp.net/cgi-bin/mailman/listinfo/parenscript-devel
parenscript-devel@common-lisp.net