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.
@BrendanEich wrote: "People keep writing bugs where callbacks or array extra downward funargs are written using 'function' and assumed to get the outer |this|. Tom Van Cutsem (an expert) did it and only caught it a while later. I've done it."
=> +1 https://gist.github.com/2279059#file_person.js Line 9-11. It took me a half hour figuring out that the age not increasing came from non-lexical this.
I see a concern that hasn't been discussed in this thread:
@polotek wrote "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."
"Then I have to decide if I want to edit library.js or find some other way to reuse it's capabilities. As I said, this happens now. But I think it will happen much more frequently with fat arrow. Simply by virtue of the fact that is a preferable syntax for writing functions, and people will use it."
=> Yes, people will misuse the short syntax. But this is not a new problem.
People generally misunderstand JavaScript. It's probably true for other languages, but JavaScript has a broader audience.
Sometimes, when I view source a website, I notice that people write "new Array()" all over the place and use the "array" as string->value maps. These often come from PHP. This is a harmless mistake except when you want to use a normal 'length' property (true story). They should be using normal objects, but they don't because they misunderstand the language.
I agree this is a problem and this will certainly hit for the shorter syntax as you and Angus predict. Especially when you need to write code that uses or works with code that does this. But this is not a language problem. It's a social problem. It's an education problem.
This is not a problem that the language itself should be aiming at solving in my opinion. This is a problem that can be solved by educating people or by designing a language that compiles down to JavaScript and is clearer to novice programmers.
"What are the criteria for Good change?"
=> My own opinion on this is that at least, education issues should not get on the way.
JavaScript is a programming language, not an easy one, people misunderstand it a lot, but it needs to evolve. Conjecturing on future misunderstanding and misuse doesn't help since it will happen no matter how the language is changed.
Regarding education, I'd like to add a word and say that I wish more people participated in JavaScript documentation. There are dozens of blog posts, tweets, jsPerfs things released each day that just get forgotten over time, because they are not maintained nor updated. Documentation is one key to solve this problem of sustainable education.
Whatever change happens in JavaScript, I hope there will be people expert enough like you, @polotek to document the new feature, how it differs from previous features and common traps. Thanks :-)