Douglas Crockford on Fat Arrow Functions in JavaScript
yuiblog.com
yuiblog.com
It's really interesting to see that bleed over from a completely different type of language.
"However, we don’t want CoffeeScript’s ->, it’s confusing to have two arrows and dynamic this binding is an oft-fired footgun."
Out-of-band info from here:
https://twitter.com/brendaneich/status/186156717506166784
https://twitter.com/brendaneich/status/186160406300082176
To me, writing 'this' as part of the parameter list for methods is more confusing than having a second arrow operator.
Edit: as per parent article, use (this, x) => { this.property = x; } instead of ->
Or you can use the Y Combinator for extra fun...
https://secure.wikimedia.org/wikipedia/en/wiki/YCombinator#E...
currently, function(){} is the exact same as the proposed ()->{}, and (function(){}).bind(this) is the exact same as ()=>{}
>"Fat arrow functions do not have prototype properties, which makes them cheaper to make. They are immutable."
Fat arrow is well understood in the JS community because of CoffeeScript, and that is one reason why people are pushing for fat arrow to be accepted. I personally think CoffeeScripts has had a very large impact on the idea.
These kinds of changes have been floating around for javascript since long before coffeescript.
One of the first ideas with CoffeeScript was to simplify function syntax, mostly because JavaScript's anonymous functions are so useful and pervasive that you end up with a lot of this:
_.each(toRemove, function(key){ delete data[key]; });
... where the "word" function there doesn't really tell you anything meaningful about what you're trying to accomplish.Arrows were appealing for a shorthand function syntax because of their visual representation of what happens in a (pure) function. Input goes in one side, output comes out the other. The input determines, or points to, the output. Since we use parentheses symmetrically to group parameters to a function, both when you define a function and when you call one, we arrive at this:
(input) -> output
... or with our initial example: _.each toRemove, (key) -> delete data[key]
That was the thinking. CoffeeScript actually originally used => for all functions, but the fat arrow distinction was introduced when we introduced bound (lexical "this") functions as an alternative to normal (dynamic "this") functions.This:
x = (a) =>
y = (b) =>
z = (c) =>
@q * a * b * c
Becomes this: var x,
_this = this;
x = function(a) {
var y;
return y = function(b) {
var z;
return z = function(c) {
return _this.q * a * b * c;
};
};
};
Instead of this: var x;
var __bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; };
x = __bind(function(a) {
var y;
return y = __bind(function(b) {
var z;
return z = __bind(function(c) {
return this.q * a * b * c;
}, this);
}, this);
}, this);(You know, the thing that was mentioned in the linked article?)
JavaScript is a beautiful language trapped in a lame syntax, peppered with poor semantic choices based on what was considered "just the way it is" back then.
I'd much rather they fixed javascript, than use coffeescript.
Although this might be unfair to coffeescript, I haven't given it a proper try-out yet :)
C functions conceptually in a half-assed attempt at making the computer behave marginally more like a Harvard Machine than a Von Neumann one.
OTOH, coroutines are easier to bring about in assembler than in C.
The "myFunction(item) for item in array" syntax also seems wrong way around. You use "item" before you say what it is.
I'm not an expert. These are just initial impressions, but coffeescript seems to have some good ideas, but tries to do too much. It would be interesting to see what thought process went into deciding to include certain constructs. Was it just an experiment? Are there reasons that might persuade me?
Ultimately the better JavaScript is also going to be JavaScript.
> It would be interesting to see what thought process
> went into deciding to include certain constructs.
Happy to oblige. There's plenty of reading material and conversations about most language decisions available here:https://github.com/jashkenas/coffee-script/issues?direction=...
As to the existence of (optional) postfix "unless" and "if" -- does it also sound backwards to you when someone says:
"Call your mother if it's her birthday."
... in English? If that doesn't sound so crazy, then consider the CoffeeScript: call mom if mom.birthday.isToday()
It's a little thing, that hopefully you can take advantage of to make short conditionals more readable then the JSLint-style JavaScript: if (mom.birthday.isToday()) { call(mom); } if mum.birthday.isToday(): call(mum)This to me looks like going out of your way to have lots of ways to do the same thing. I never cared for it in PERL either.
The argument that "it reads like English" is not one that I like much - The history of making programming languages read like English is a long succession of dead ends. Programming languages work more like formal maths proofs than they do like English prose. Rather make the language readable on its own terms.
There certainly have been notable failures, such as Applescript, but I find it hard to dismiss Coffeescript, Ruby, SQL and FORTRAN which have all been quite popular.
You left out a notable example of Cobol - Which would you rather read: "Add 1 to someValue Giving someValue", or "someValue++" ?
Hell, it's very similar to how "map" works in most functional languages -> "map function items"
"myFunction(item) for item in array" looks like "call myFunction on "item", which is not yet defined... oh now it is." It's backwards.
Besides, couldn't the same argument be made about C? Sure I know a lot of people 'like' C, but I don't think I've ever heard of it being referred to as 'beautiful'...
(flame prevention: this is kind of a joke. i understand that it actually is pushing towards a better language, it's just such a slow and painful process compared with just using coffeescript)
Whenever I pass a simple and short function, for example as a predicate to grep/filter or as a tiny implementation for map/reduce I feel that "function" is half of what I type - and distracting. Worse, explicitly "return"ing adds more noise.
Most of my anonymous functions are really, really small. If they are usually on the level of "d % 2 == 0" or "d.slice(42)" then removing the overhead of "function (d) { return" seems a good idea. Not a huge deal, but nice nevertheless.