I promised some people that I would talk a little about my feelings on ECMAScript proposals. I love javascript as a language. Sure, it has lots of warts, some that aren't easily dismissed. But it also has some really nice constructs that allow for elegant code solutions. My preference for javascript is purely subjective, and I don't mind admitting that. But being that I'm a staunch supporter of the language and the community, I'm also pretty opinionated about where it's going. These are just some of my concerns.
I should start by saying that I'm not against progress. Whenever I argue with people about javascript proposals, I always get the eventual argument that we have to move javascript forward and we can't be afraid of change. I want to go on the record as saying I want upgrades to javascript. But I don't think progress is a reason not to challenge ideas that I think are not fully formed or potentially problematic. This tension is good, because it keeps the standards makers on their toes. And it makes sure they get alternate input from people who have a different perspective on what makes a good language feature, but who are still invested in moving things forward.
Many ECMA proposals solve problems with the language, that's a given. And you can't really change a well-established language without creating other problems. That's unavoidable and shouldn't be a barrier to progress. My concern with some of the proposals is the impact of these other problems isn't always given enough weight in determining if the change is worth it, https://twitter.com/#!/polotek/status/187219527459811330.
I think the recent concensus on fat arrow syntax is a good example to illustrate this. I think it's a decent proposal. I'm not sure I agree that "fixing" dynamic function context with syntax is absolutely necessary. But after talking to several people, I seem to be in the minority, so I can accept that this is happening. It's also a fairly simple proposal on it's face. If you use the =>
syntax, you'll get a function. And that function will have a few other "nice" properties, like automatic binding to the closest lexical this
.
On the face of it, this seems like pure win. People want shorter function syntax and people want to worry less about this
. But this proposal has side effects, and more importantly it has affordances, that shouldn't be ignored. Most of these are expressed pretty well in this article by Angus Croll. In short, I'm concerned that people will use fat arrow, a lot, everywhere, and that's a problem.
Fat-arrow isn't just an alternative to normal function syntax. It's a new syntax that also introduces a completely new type of function. Functions that come from fat arrow have significantly different properties from normal functions. Some of the things you expect from normal functions are not applicable to fat arrow functions.
- Functions have dynamic
this
, fat functions always have athis
that you can't anticipate. - Functions can be dynamically dispatched with call/apply. Call/apply works with fat functions, but it will not change the context. Only pass arguments.
This is only a couple of items. There are several more differences that have to do with how the function body works. But these 2 have to do with functions that are passed around. These are differences that every developer who uses apis will have to deal with.
For one example, you if you take an object and mix it's methods onto your own object, you have to be aware of whether the functions are already bound. Otherwise you won't get expected behavior. Yes this is already a possibility with Function#bind
or closures, but it doesn't happen very often. It's not a common occurence. And this gets at the heart of my concern. I think it's very possible that fat arrow will become very common. Because as Angus points out, it will also be the shortest way to get a function. Programmers love short syntax. And they will jump on this. Unfortunately those same developers who don't get dynamic context, the ones we are trying to save, may not bother to be selective in when they use fat arrow functions vs normal ones. So we'll get proliferation of these things. And then it'll become a real problem for anyone who is used to taking advantage of the flexible power of javascript.
How big a problem is this? I don't know. It's certainly more of an unknown than the misunderstanding of dynamic this
. But from my long history with javascript, I think it's a potentially large issue. I think it's one of those things that gets away from you and eventually people are saying "you can't really trust call and apply, you don't know what kind of function you're getting". Or everyone's code is littered with some isBound type check and they continue to gripe about javascript's inconsistency.
But I could be way off base. This could be totally unfounded. Does anyone know how likely this type of thing is? How was it decided that the benefits of fat arrow outweight these potentially long-lasting detriments? Are there any plans to mitigate? These are the questions I'm left with once a "consensus" has been reached. I would love to have nothing better to do than pore over the es-discuss lists, but I just don't have the time. So I try to give my input on things as they gain enough popularity to get some publicity. And I don't always have constructive alternatives to present.
This is where I'm coming from when I scrutinize harmony proposals. Fat arrow isn't the only example; just the most recent. As an attempt to do more than just gripe, I think what would help is to publish concerns about the proposals and the rationale that minimizes those concerns. And even more helpful would be some talk about what criteria are concidered when evaluating proposals. When is battling current confusion more important than introducing new inconsistency? Why do we feel like the new weirdness will be less onerous?
I hope none of this feels like disparaging the work of standards body, and I hope it serves to clarify my views on progress. I don't know if I'll find more time to be a larger part of es-discuss and get in on these things earlier in the process. But I can promise not to be a person who just complains. Looking forward to feedback.
I didn't mean for the discussion to devolve into talk about just fat arrow. I really appreciate all the info here though. It has been helpful. I'm more than satisfied with the answers here on why fat arrow is a Good Thing™.
I guess I'm still not sure how the responses from @dherman and @BrendanEich serve to convey how we plan to mitigate the potential follow on problems with these changes to the language. What I'm reading is "that's not what they're for" or "I don't think that's a problem". I see the stats that suggest that the benefits of the proposal are there. But there's no data to suggest that the pitfalls won't end up being larger than we anticipate. Just like we couldn't anticipate dynamic
this
being such a huge problem. An advanced feature to be sure, but not a "we have to change the language to protect people from this" level of problem. (maybe Brendan did and it just couldn't be helped)In fact reading back over the answers here, it seems more alarming. If fat arrows hit 90% of use cases, why wouldn't people just use them all the time? This seems to suggest they'll even appear in places where they shouldn't. The combination of short syntax and the fact that it's probably 90% what you want is a recipe for the same type of blind usage that makes people use
===
everywhere without thinking about it.It's also relevant to note that my first inclination when using fat arrows was that they could go into an object literal as methods. It turns out that was wrong. But it also suggests that it's non-intuitive. And instead of working this out between plain old functions and a new, second type of function, we instead point people to yet a third way to create functions. I would argue that the method shorthand syntax also suggests that the functions will be bound. Not to lexical
this
but to the object being defined. It looks like they belong to the object because they are part of the syntax of defining it, but that's not the case. So what we're looking at is, we've attempted to separate the various usages of functions and given them their own syntax to help differentiate intent. But we've made it less intuitive to reason about the behavior of these, or to learn that behavior and keep it in your head without the need to look it up again.This is the type of confusion and inconsistency I'm worried about. So outside the context of fat arrow, I want to pose the original questions again. How much weight do these concerns get? How do we decide how likely they are to be a problem or how do we mitigate them? What criteria does TC39 use to answer these questions?