Implement arrow functions in v8
code.google.com
code.google.com
edit: after following 4 links I finally found the bug report about it
This commit moves them from "behind the experimental flag" to "shipping by default" in Chromium. It's a pretty big deal to people who write JS for a living.
var square = function (a) { return a * a;}
You can write: var square = a => a * a; // foo takes a function, and a boolean.
// foo(a=>7, a>=2);
Really? That's easy to read is it? Eugh count me out.It's like when languages make threads easy to create - and then programmers go away and use threads for everything!
Maybe some verbosity is a good thing because it makes programmers think about whether they really want to do something a few thousand times.
Also, your tone is bad.
I think a better argument would have been that adding something that appears to just be a shorthand for writing functions is a potential footgun to language newcomers, but I think that argument is still relatively weak.
At point have stop called . Just you represent same by more doesn't that not to an on of to cognitive , otherwise all programming switches.
My point is, removing "function" and "return" from the syntax, won't necessary easy cognitive load, at least not for senior JavaScript coders. It will save bandwidth though! :P
function(arg) {statement;}.bind(this)
setTimeout(() => this.someMethod(), 1000);Of course any syntax can be abused in such a way to create ugly code. But if I compare
[1, 2, 3].map( a => a * a ); // [1, 4, 9]
to [1, 2, 3].map(function(a) { return a * a; });
I prefer the former. It's more concise, and strips off a lot of visual noise, and I think it's more readable (the intent isn't wrapped in lots of boilerplate).That doesn't mean one can't write horrible code with the arrow form. Of course you can. Furthermore, it's not necessarily something you should use all the time, because it's not completely analogous to a normal `function` because it binds `this` lexically. Which means `function` isn't going away any time soon, especially if you need to bind them dynamically.
In short: use the best (syntactic) tool for the job. There are use cases where the arrow makes sense semantically, and there are cases where it doesn't. Use as appropriate, as one should always do.
list.map(function(x) { return x * 2; });
verses list.map(x => x * 2);
The actual functionality of the first is swallowed in visual noise (function, return). Yes, it's something new to learn for Javascript programmers, but it's useful and makes the meaning of code clearer.That's not even touching on the this-binding element, which is also incredibly useful in common Javascript code.
And anyone competent with any language implementing map can easily read:
users.map(user => user.name);
...without having to do any "skimming over" the noise. It's not a big difference, you're right, but it's the kind of little thing that, when you let it build up over time, gives you the "write-everything-in-triplicate" feel of Java 6.Further, you have to be intimately familiar with Javascript to understand why this is necessary:
function fetchUserData(){
var self = this;
userService.fetchAllUsers()
.then(function(fetchedUsers){ self.users = fetchedUsers; });
}
or even this: function fetchUserData(){
userService.fetchAllUsers()
.then(function(fetchedUsers){ this.users = fetchedUsers; }.bind(this));
}
as opposed to simply writing: function fetchUserData(){
userService.fetchAllUsers()
.then(fetchedUsers => this.users = fetchedUsers);
} someObject.foo = function() {
someObject.bar = 123;
}
function Foo() {
var Foo = this;
Foo.bar = 456;
}
Pro tip: Always do asynchronous operations Before presenting the object to the program state. Or you will see "undefined" bugs in production!The lambda function is a foundational construct in computer science (1936), and it is often written using an arrow. Hipster fluff it is not.
let sqr = x => Math.pow(x, 2)
let property = name => obj => obj[name]
let distance = p1 => p2 => Math.sqrt(sqr(p2.x - p1.x) + sqr(p2.y - p1.y))
let byComparing = f => (x, y) => {
let fx = f(x), fy = f(y)
fx < fy ? -1 : fx > fy ? 1 : 0
}
let points = [{x: 1, y: 2}, ...]
let byX = points.slice().sort(byComparing(property('x'))
let byStartDistance = points.slice().sort(byComparing(distance({x: 0, y: 0})) let sqr = x => Math.pow(x, 2)
let distance = (p1, p2) => Math.sqrt(sqr(p2.x - p1.x) + sqr(p2.y - p1.y))
const zero = Object.freeze({x: 0, y: 0})
let byX = points.slice().sort((p1, p2) => p1.x - p2.x)
let byStartDistance = points.slice
.sort((p1, p2) => distance(p1, zero) - distance(p2, zero))
It's not nearly as composable, sure, but I think almost everyone would understand it much faster. The curried `distance` would also be a bit annoying to reuse in other contexts where you'd have to write `distance(p1)(p2)` instead of the idiomatic (at least now; idioms can change) `distance(p1, p2)`.That said, the arrow function is a massive win in both examples. I've been using it for a while and never had any issue mistaking it with <= or >=. The linter would probably catch it anyway.
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Refe...
a=>b<=7
a>=b<=7
Can you not see the typos possible with this? The less characters you use for something, the more error prone. There's a reason we don't write in regular expression syntax.Maybe I'm just getting old!
var self = this;
foo(function(x) {
return x + self.y;
});
rather than: foo(x => x + this.y)
is so much less error-prone?If you miswrite "function" as "fnuction", you'll easily, quickly find out.
If you miswrite => as >= it might take ages to track it down.
If the function `foo` is defined as taking a function as its first argument (or even more precisely, a function which takes a number and returns a number), and you try to give it a boolean, then the static type checker will yell at you, and you'll just as easily find out as that fnuction typo.
EDIT: Now I got your point - you could accidentally assign a boolean value to a variable when you intended to create a function. One word - compile time type checking. Okay, four, Übersetzungszeittypprüfung in German.
a => { return b <= 7; }
Sure you can write it without that, but only if you want to write willfully unclear code to annoy people, like writing an entire function body on one line. Just because you can do that doesn't mean that functions are inherently unclear.If you're going to write it out, you might as well just add the `function` keyword for clarity because you're not saving a ton of keystrokes.
function(a) { return b <= 7; }All of the examples that look confusing are artificially simple and doing things you wouldn't normally try to do.
People aren't kidding when they say Perl looks like line noise, but you get used to it and can find your way through even a dizzying regular expression with relative ease over time.
Yes, $s=~s+s+S+s+$s is valid Perl.
Suggesting that things like => are "too confusing" for JavaScript is to suggest that people that write JavaScript are too dumb to handle it. Is that what you're implying here?
Some programmers write in one language, but many write in several. Having the same shorthand available in JavaScript as in C# is a big deal, it makes things feel better. Being able to apply what you've learned in one domain directly to another is more efficient than having some ridiculously quirky JavaScript-only way of doing something.
That some people will abuse it or be confused is a problem that can be overcome with a little bit of learning. It's not a big deal.
That is one of the features my colleagues most cite as justification for using babel.js (I wouldn't mind destructuring assigment either). I would love to be able to avoid transpilation since it adds overhead from making out our toolchain more complex and makes debugging more difficult because stack traces and line numbers don't necessarily match up.
You can tell by the number of CLs that a lot of work has been done already but there are a few more still in progress. It's probably still a few weeks out.
Disclaimer: I don't speak for the V8 team, I'm just an interested onlooker.
[1] - https://code.google.com/p/v8/issues/detail?id=2700#c47
Sometimes the code explains itself though!?
allowed = members.filter(member => member.age >= ageLimit);