More concise arrow functions
On Jul 26, 2013, at 8:50 AM, Domenic Denicola <domenic at domenicdenicola.com> wrote:
Why do arrow functions require a parameter list and a body? That is, none of the following are allowed:
=> foo
I guess this could be lexically unambiguous, but i'm unconvinced that the "win" of losing two characters in the strictly less common no parameters is worth the syntactic confusion
bar =>
=>
I think an optional tail would be a huge coding hazard - a typo could result in bizarre behaviour, take:
blah(=>,5)
vs
blah(=>5)
Instead you need the more-verbose
() => foo
Honestly I'm not sold on the {} free production, but i understand the arguments for it. Randomly (and because i'm too lazy to check) how would
a => b => c
produce? I mean aside from making the maintainers cry.
From: Oliver Hunt [oliver at apple.com]
I guess this could be lexically unambiguous, but i'm unconvinced that the "win" of losing two characters in the strictly less common no parameters is worth the syntactic confusion
No-parameter functions are pretty darn common, especially if you count cases where the function might normally take parameters but you don't care about them in this case.
A very common case is in unit testing libraries, which would look like so:
describe("addition", => {
it("should work", => {
expect(2 + 2).toEqual(4);
});
});
I think an optional tail would be a huge coding hazard - a typo could result in bizarre behaviour
This has not been my experience in CoffeeScript, and I haven't heard of such experiences from any of the language's other users either.
how would
a => b => c
produce?
a => (b => c)
is the only option; (a => b) => c
is not syntactically valid since (a => b)
is not a valid ArrowParameters
.
I proposed arrow functions and championed them into ES6. As the strawman
history shows, eliding ()
and {}
were both supported at first:
doku.php?id=strawman:arrow_function_syntax&rev=1332877190
Note the _opt suffixes in the productions.
Meeting notes at
don't cover the cuts, but es-discuss threads do:
It really was a gestalt negative reaction. The grammar issues can be dealt with. People just objected on the basis of (=>)
or (=>42)
being too cryptic, IIRC. In the interest of gaining consensus, I cut the controversial bits.
Now on to Oliver's followup, which may give more detail.
Oliver Hunt wrote:
On Jul 26, 2013, at 8:50 AM, Domenic Denicola<domenic at domenicdenicola.com> wrote:
Why do arrow functions require a parameter list and a body? That is, none of the following are allowed:
=> foo
I guess this could be lexically unambiguous, but i'm unconvinced that the "win" of losing two characters in the strictly less common no parameters is worth the syntactic confusion
For the record, I validated toy grammars and making arrow's parameter list optional is completely unambiguous.
bar =>
=>
I think an optional tail would be a huge coding hazard - a typo could result in bizarre behaviour, take:
blah(=>,5)
vs
blah(=>5)
Perhaps more likely to be a problem:
var empty = =>
callLater(empty, "sorry");
due to left out semicolon at end of first line.
Instead you need the more-verbose
() => foo
Honestly I'm not sold on the
{}
free production, but i understand the arguments for it. Randomly (and because i'm too lazy to check) how would
a => b => c
a => (b => c)
of course.
produce? I mean aside from making the maintainers cry.
Maintainers put on the big-kid pants every day. We have lovely theory of
formal languages and parsers, there's no issue with chained =>
. It's actually good notation from Math and CS, supported directly by many languages.
From: Brendan Eich [brendan at mozilla.com]
I proposed arrow functions and championed them into ES6. As the strawman history shows, eliding () and {} were both supported at first:
Right, I remember {}
being optional at least; in fact the genesis of this thread was me working with Traceur this morning and getting complaints when I tried () =>
. I certainly don't blame you for making them mandatory to gain consensus! It was hard enough to get arrow functions through.
I started this thread hoping we could get some reconsideration, now that arrow functions have been a consensus reality for so long that it's hard to imagine ES6 without them. I find it especially baffling that there's such a negative reaction given the time-tested nature of optional ()
/{}
in CoffeeScript.
Domenic Denicola wrote:
From: Brendan Eich [brendan at mozilla.com]
I proposed arrow functions and championed them into ES6. As the strawman history shows, eliding () and {} were both supported at first:
Right, I remember
{}
being optional at least; in fact the genesis of this thread was me working with Traceur this morning and getting complaints when I tried() =>
. I certainly don't blame you for making them mandatory to gain consensus! It was hard enough to get arrow functions through.
I'm not worried about blame (I blame me on this :-P), but there's a lesson here. Not everyone can swallow CoffeeScript as solid and long-standing precedent. Too few even know it on TC39, but that's not just a criticism of TC39ers -- it cuts both ways since CoffeeScript is not old or widely studied compared to other languages. More below.
I started this thread hoping we could get some reconsideration, now that arrow functions have been a consensus reality for so long that it's hard to imagine ES6 without them. I find it especially baffling that there's such a negative reaction given the time-tested nature of optional
()
/{}
in CoffeeScript.
Optional parameter list is an easier sell since =>
is very unlikely to start a statement, while =>
may well end one and lack of semicolon means that the statement continues. This is the "lack of ASI where I expected
it" hazard I mentioned in reply to Oliver.
But again, "time-tested" and CoffeeScript make some of us old-timers laugh. FTR, I like CoffeeScript and Jeremy was kind enough to let me co-present at JSConf 2011 in Portland. However, it is young.
One company I advise tried it, and found that its "unsyntax" bit back in this way: code that compiled and seemed to do one thing did something quite different. This happens with JS due to ASI; it also happens just due to the C syntax heritage. But it happens more often with CoffeeScript, from what I hear.
=> foo
None of the others, but this variant would be nice from a purely aesthetic point of view. There's something vaguely visually unappealing about the empty parens followed by the arrow.
Arguing with myself...
Brendan Eich wrote:
Optional parameter list is an easier sell since
=>
is very unlikely to start a statement, while=>
may well end one
"may well" is too strong. My example in reply to Oliver was
var empty = =>
callLater(empty, "sorry");
But it's hard to think of anything else that might end an intended
statement with =>
.
Anyway, thanks for bringing this up. Sometimes TC39 needs to reach consensus in stages, e.g., maximin classes, only then to realize what most people could see: we need less minimal maximin (e.g., class "statics"). Could happen with arrows, but I wanted to provide some more detailed guidance -- and a cautionary tale re: CoffeeScript.
Honestly I would prefer that the parens be mandatory all the time, right now it's just confusing to explain when it has so many variations.
A useless parameter is an option:
_=> 'foo'
One company I advise tried it, and found that its "unsyntax" bit back in this way: code that compiled and seemed to do one thing did something quite different. This happens with JS due to ASI; it also happens just due to the C syntax heritage. But it happens more often with CoffeeScript, from what I hear.
More of an issue with CoffeeScript's grammar, which is ambiguous in lots of places, and with what I believe to be some bugs in the parser (those Michael Ficarra could probably fix in CoffeeScript redux). I had some examples back in the days I tried CoffeeScript where one-character differences in an object declaration could lead to four entirely different object definitions.
On 7/26/2013 11:53 AM, Michael Haufe wrote:
A useless parameter is an option:
_=> 'foo'
This seems to be an argument in favor of making the params completely optional. The fact that throwing in a useless param is more concise than having zero params (due to paranthesis requirement).
I think the semicolon hazard is enough to make omitting the body questionable, but omitting the params is an easy win with no downside.
I'll put it on the agenda for the September TC39 meeting.
+1
+1
My perspective: I don’t see a use case for a missing body, but a missing parameter list would be very useful – to delay the execution of a block of code. It also makes much sense visually:
2. (x, y) => { ... }
1. x => { ... }
0. => { ... }
I agree a missing body is usually weird; the only case that really makes sense is =>
, which is especially useful in default parameter lists:
function tryCatchFinally(tryF, catchF = =>, finallyF = =>) {
// ...
}
This is full-on bikeshedding, but I’d prefer a constant for this purpose (less grawlixy):
import { NOOP } from 'someModule';
function tryCatchFinally(tryF, catchF = NOOP, finallyF = NOOP) {
// ...
}
Function.prototype
could be used, too. But I don’t like that at all.
Why do arrow functions require a parameter list and a body? That is, none of the following are allowed:
=> foo
bar =>
=>
Instead you need the more-verbose
() => foo
bar => {}
() => {}
Any chance of relaxing this a bit?