More concise arrow functions

# Domenic Denicola (12 years ago)

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?

# Oliver Hunt (12 years ago)

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.

# Domenic Denicola (12 years ago)

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.

# Brendan Eich (12 years ago)

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

esdiscuss/2012-March/021872

don't cover the cuts, but es-discuss threads do:

esdiscuss/2012-April/022178

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.

# Brendan Eich (12 years ago)

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.

# Domenic Denicola (12 years ago)

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.

# Brendan Eich (12 years ago)

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.

# Kevin Smith (12 years ago)
  • => 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.

# Brendan Eich (12 years ago)

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.

# Matthew Robb (12 years ago)

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.

# Michael Haufe (12 years ago)

A useless parameter is an option:

 _=> 'foo'
# Quildreen Motta (12 years ago)

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.

# Brandon Benvie (12 years ago)

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.

# Brendan Eich (12 years ago)

I'll put it on the agenda for the September TC39 meeting.

# Nathan Wall (12 years ago)

+1

# Axel Rauschmayer (12 years ago)

+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. => { ... }

# Domenic Denicola (12 years ago)

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 = =>) {
  // ...
}
# Axel Rauschmayer (12 years ago)

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.