Different semantics should have different-looking syntax
On 21.05.2011 23:37, Brendan Eich wrote:
For strawman:block_lambda_revival I have written up the Ruby-inspired {|x| x * x} syntax.
First, this proposal is also useful for JS. Especially the semantics of returning from a closure (so this is what TCP addresses, now I see that it's not the "Transmission Control Protocol" :D, and actually I myself addressed this issue long time before - bit.ly/eVq5ob (JFTR), though without mentioning Tennet's principle).
Currently we have to use try-catch to handle simple search engine with
using e.g. forEach
for that. So using return
inside the
block-closure will exit all block contexts -- as an exception would be
thrown and caught at non-block level (i.e. at function level), right? At
least Ruby uses such a way. And we use "return-less" return, i.e. just
via control-flow structure, then a block return to the caller. It seems
a good addition.
It turns out now that it's really a dilemma what to choose -- arrows or blocks... have to think.
Dmitry.
On May 21, 2011, at 12:37 PM, Brendan Eich wrote:
For strawman:block_lambda_revival I have written up the Ruby-inspired {|x| x * x} syntax.
Alternatives (ignoring keyword issues) that look more like function syntax (Peter's suggestion of lambda (x) { x * x }, e.g.) seem worse in this light: block lambdas do follow the correspondence principle, which is novel to JS with its C statements for control effects heritage.
In this light, the use of | | to bracket formal parameters seems better than anything using (...) {...}. This is not an overriding concern, but it seems worth mentioning. We want block-lambdas or any such TCP-pure new thing to have syntax that says "look! something new here".
And, since the strawman builds on block syntax,
Urgh, I meant to write "supports building control abstractions that mimic keyword-head governing block syntax", or something like that. Came off as circular arguing the way I wrote it.
we want the new form to have syntax that "looks like a block", in which you'd expect TCP purity for break, continue, return, |this|, and arguments.
Point is we want light weight, control abstractions, TCP, lambdas. In the proposal this leads to (a) block lambdas; (b) paren-free calls provided actuals are block lambdas.
On May 21, 2011, at 1:18 PM, Dmitry A. Soshnikov wrote:
First, this proposal is also useful for JS. Especially the semantics of returning from a closure (so this is what TCP addresses, now I see that it's not the "Transmission Control Protocol" :D, and actually I myself addressed this issue long time before - bit.ly/eVq5ob (JFTR), though without mentioning Tennet's principle).
(Tennent)
Currently we have to use try-catch to handle simple search engine with using e.g.
forEach
for that. So usingreturn
inside the block-closure will exit all block contexts -- as an exception would be thrown and caught at non-block level (i.e. at function level), right?
In the spec, new completion types that act like exceptions, yes. I'm not proposing that we reify BREAK, CONTINUE, and RETURN as catchable exceptions, though.
At least Ruby uses such a way. And we use "return-less" return, i.e. just via control-flow structure, then a block return to the caller.
I argue this wants strawman:completion_reform in the strawman.
It seems a good addition.
Thanks, I think so too.
It turns out now that it's really a dilemma what to choose -- arrows or blocks... have to think.
Arrow function syntax is "just syntax". I will drop it if we can agree on block lambda revival. As @_sjs (Sami Samhuri) tweeted at me, "We'll always have function." ;-)
On Sat, May 21, 2011 at 1:24 PM, Brendan Eich <brendan at mozilla.com> wrote:
It turns out now that it's really a dilemma what to choose -- arrows or blocks... have to think.
Arrow function syntax is "just syntax". I will drop it if we can agree on block lambda revival. As @_sjs (Sami Samhuri) tweeted at me, "We'll always have function." ;-)
I was worried that using these lambda blocks would be heavier-weight for the functional idiomatic use cases where -> really shines. But since this
proposal also allows an implicit return, this actually ends up being even more terse than -> functions:
let names = people.filter((p) -> p.lastName == 'Smith').map((p) ->
p.firstName); let names = people.filter({|p| p.lastName == 'Smith'}).map({|p| p.firstName});
For me, this is pretty compelling. It covers both the "roll your block structure" use case and the "lightweight lambda" one. Nice!
On May 21, 2011, at 9:57 PM, Bob Nystrom wrote:
On Sat, May 21, 2011 at 1:24 PM, Brendan Eich <brendan at mozilla.com> wrote:
It turns out now that it's really a dilemma what to choose -- arrows or blocks... have to think.
Arrow function syntax is "just syntax". I will drop it if we can agree on block lambda revival. As @_sjs (Sami Samhuri) tweeted at me, "We'll always have function." ;-)
I was worried that using these lambda blocks would be heavier-weight for the functional idiomatic use cases where -> really shines. But since this proposal also allows an implicit return, this actually ends up being even more terse than -> functions:
let names = people.filter((p) -> p.lastName == 'Smith').map((p) -> p.firstName); let names = people.filter({|p| p.lastName == 'Smith'}).map({|p| p.firstName});
For me, this is pretty compelling. It covers both the "roll your block structure" use case and the "lightweight lambda" one. Nice!
Good one-liner A/B comparison -- thanks.
/be
P.S. This will help kill something in ECMA-357, E4X, that is sugar for 'with', where the sugar hooks the kids on the poison. The lightweight syntax of blocks is just about needed, including paren-free calls (not used in your example, good choice -- and good to have the choice).
On Sat, May 21, 2011 at 12:37 PM, Brendan Eich <brendan at mozilla.com> wrote:
For strawman:block_lambda_revival I have written up the Ruby-inspired {|x| x * x} syntax.
Alternatives (ignoring keyword issues) that look more like function syntax (Peter's suggestion of lambda (x) { x * x }, e.g.) seem worse in this light: block lambdas do follow the correspondence principle, which is novel to JS with its C statements for control effects heritage.
In this light, the use of | | to bracket formal parameters seems better than anything using (...) {...}. This is not an overriding concern, but it seems worth mentioning. We want block-lambdas or any such TCP-pure new thing to have syntax that says "look! something new here".
I don't think this idea of needing different syntax for different semantics is a strong point in favour of the {||} syntax. ECMAScript programmers are already accustomed to the keyword(){} syntax template and have no trouble understanding the difference between the following two bits of code and what return means in each.
if(a){return a;}
function(a){return a;}
And, since the strawman builds on block syntax, we want the new form to have syntax that "looks like a block", in which you'd expect TCP purity for break, continue, return, |this|, and arguments.
Lambdas are useful for more than just blocks in control structures. I don't think that use should be the sole force behind choosing the syntax.
Peter
On Jun 4, 2011, at 7:24 PM, Peter Michaux wrote:
On Sat, May 21, 2011 at 12:37 PM, Brendan Eich <brendan at mozilla.com> wrote:
For strawman:block_lambda_revival I have written up the Ruby-inspired {|x| x * x} syntax.
Alternatives (ignoring keyword issues) that look more like function syntax (Peter's suggestion of lambda (x) { x * x }, e.g.) seem worse in this light: block lambdas do follow the correspondence principle, which is novel to JS with its C statements for control effects heritage.
In this light, the use of | | to bracket formal parameters seems better than anything using (...) {...}. This is not an overriding concern, but it seems worth mentioning. We want block-lambdas or any such TCP-pure new thing to have syntax that says "look! something new here".
I don't think this idea of needing different syntax for different semantics is a strong point in favour of the {||} syntax. ECMAScript programmers are already accustomed to the keyword(){} syntax template and have no trouble understanding the difference between the following two bits of code and what return means in each.
if(a){return a;}
function(a){return a;}
Yes, but if you give them
lambda(a){return a;}
and tell them that, when that lambda is invoked, the 'return a;' returns from the outer function (if active) or throws, many will have an OMGbad reaction.
I kid you not.
Now it may be that the same cohort reacts just as badly to
{|a| return a; }
I know at least a few people who did react badly to the former, and do not react badly to the latter -- precisely because the latter looks like a block.
But who knows? We're trading anecdotes and assertions.
The big problem for anyone who wants TCP-conformant lambdas, whatever the syntax, is the anti-TCP cohort.
And, since the strawman builds on block syntax, we want the new form to have syntax that "looks like a block", in which you'd expect TCP purity for break, continue, return, |this|, and arguments.
Lambdas are useful for more than just blocks in control structures. I don't think that use should be the sole force behind choosing the syntax.
You have it backward. The problem last time was that syntax too much like function, with violently different return/break/continue/this semantics, caused consternation. Such semantics cause no problem in blocks. Wherefore, block-lambdas.
This does not mean everyone (definitely you are an exception) objects to TCP.
It does mean that we are not going to standardize function-looking lambdas with TCP conformance. Whether we can standardize anything with TCP conformance remains to be seen.
For strawman:block_lambda_revival I have written up the Ruby-inspired {|x| x * x} syntax.
Alternatives (ignoring keyword issues) that look more like function syntax (Peter's suggestion of lambda (x) { x * x }, e.g.) seem worse in this light: block lambdas do follow the correspondence principle, which is novel to JS with its C statements for control effects heritage.
In this light, the use of | | to bracket formal parameters seems better than anything using (...) {...}. This is not an overriding concern, but it seems worth mentioning. We want block-lambdas or any such TCP-pure new thing to have syntax that says "look! something new here".
And, since the strawman builds on block syntax, we want the new form to have syntax that "looks like a block", in which you'd expect TCP purity for break, continue, return, |this|, and arguments.
Thus, block lambdas that start with { and have lightweight parameter delimiters.