16

ES6 added fat-arrow functions (=>), which have two major differences from normal functions:

  • shorter syntax (including implicit return if you use a single-expression body)
  • inherit this from surrounding scope

These are both very useful features, but seem to me completely separate in their value and application – sometimes I want one, or the other, or both, or neither. It seems odd that if I want to use a short-syntax function, I have to also use the this-modifying behaviour. And vice versa. I don't see why these two capabilities are implemented as a single addition to the language.

What if I want to use a short syntax function for its implicit return and brevity (in some context where a full function (..) { return ...} would be slightly less readable), but I want to use this in my function to refer to the calling context? There's no way to do this.

CoffeeScript has both -> and => style functions, and apparently ES6 borrowed the => style from there. So my question is, why didn't ES6 also borrow the -> style?

Robert Harvey
  • 198,589
  • 55
  • 464
  • 673
callum
  • 10,377
  • 9
  • 30
  • 33
  • fat-arrow functions have other differences, like they can't bind `arguments` either. – DeadMG Dec 29 '15 at 12:36
  • If at times all you want is the surrounding scope, you can always bind `this` to the closure in a full function declaration. This might not be the part you are concerned about though. – Ben Jan 11 '18 at 22:46

2 Answers2

26

See the proposal to add arrow functions: http://wiki.ecmascript.org/doku.php?id=harmony:arrow_function_syntax1

What it says is:

However, we don’t want CoffeeScript’s ->, it’s confusing to have two arrows and dynamic this binding is an oft-fired footgun.

You can also see some discussion of a previous version of the proposal which did have the -> syntax as well: https://esdiscuss.org/topic/arrow-function-syntax-simplified

It appears to come down to the following:

  1. Having two arrow syntaxes with subtly different semantics would increase complication and confusion.
  2. The dynamic this binding of function() and -> was deemed rarely useful, and a foot-gun.
  3. If you really need dynamic this binding, you can still use function(), having a shortcut syntax wasn't very helpful.
Winston Ewert
  • 24,732
  • 12
  • 72
  • 103
  • 1
    +1. Note specifically that ES6 is the second attempt at introducing these features, which were originally planned for inclusion in ES4, but the spec was abandoned when it became clear that major stakeholders thought it was too complex and likely to break backwards compatibility. Keeping everything as simple as possible must have been an important goal for the committee this time. – Jules Dec 29 '15 at 19:05
  • 1
    Thanks for your answer but I don't think it covers it. Less doesn't mean simpler; I'd argue it's more complex having to switch between two very different function syntaxes just to get different this-binding logic (compared to switching a single character). Having "multiple types of functions with varying semantics" is not a terrible idea; it's exactly what we do have in fact. And I don't see what backwards compatibility has to do with anything we're talking about. I'm not suggesting they should have removed support for the classic function syntax, if that's what you mean – callum Dec 29 '15 at 21:38
  • 3
    @callum, the consensus (at least among the people making this decision) is that `function()` style this binding was a mistake and is a wart on the language. If they could, they'd change `function()` to have `=>` semantics, but they can't because that would break backwards compatibility. – Winston Ewert Dec 29 '15 at 21:50
  • 2
    @WinstonEwert hang on, are you saying the people making the decision would have preferred if they could change `function()` to inherit `this` from surrounding scope like `=>` does? In that case, wouldn't `this` just refer to the global object everywhere? Sounds weird. Where did you hear that? – callum Jan 04 '16 at 17:43
  • @callum, I rewrote my answer using links to the discussion and proposal. Obviously, having this be the global object everywhere would be pointless. I don't know what semantics they would have chosen if they could have, but the existing semantics are described as a foot-gun. – Winston Ewert Jan 04 '16 at 18:35
  • 1
    Awesome, thanks. This is what I was looking for. Still a bit confused about the apparent disapproval of dynamic `this`-binding, especially seeing as ES6 class methods use it, and seeing as you have to use it if you want a function to have a name. It feels to me like a weak attempt to half-bury a core feature of the language; even if that feature should never have existed, half-burying it seems like it would make it even more of a footgun. Anyway thanks for the answer. – callum Jan 04 '16 at 19:21
  • @callum, yeah, some of the choices made by the ES6 people seem suspect to me. – Winston Ewert Jan 04 '16 at 23:38
  • 1
    I was wondering about this too, but my question is, why, once it was decided that two versions was too confusing, etc., and one was fine, why "=>" instead of "->". I'd save => for a latter discovered need, unless -> really broke compatibility with something. I didn't read anything that said the "-" character would break something. Also, and I know I'm an edge case here, but with QUERTY you have to reach a finger up to the top row in both cases, but on DVORAK, "-" is on the home row, right next to "s", so "->" is like butta, but "=>" is slower. – Brian Chandler Mar 11 '16 at 20:18
  • @BrianChandler, from the discussion I linked to in this post, it looks like they did it for comparability with coffeescript. If they had used ->, they would have add used -> to mean what coffeescript calls =>, and that would have been needlessly confusing. – Winston Ewert Mar 11 '16 at 20:53
  • 4
    This may have an accepted answer, but it seems like poor language design. If you have a language that requires a fat arrow, then a thin arrow should be available as well. The former forces everyone to begin thinking in terms of objects, whereas the latter acknowledges javascripts history of functional design first, and deferred context. – Core Apr 13 '16 at 18:18
-2

Because they didn't invent it. They took CoffeeScript/LiveScript idea and modified it, they thought it would be better (which is not, imo, because basic always win technically).

When I say "they" I mean that there is no author, no one is responsible and you won't have any complains about the idea itself.