I'd like to see a performance comparison with older versions. Some people here noted that these new ES2015/ES6 features are hurting the performance of old features. I have no idea whether this is true, so I think it would be best to just have the numbers.
A bigger 'issue' for now is that most ES2015 features are (much) slower than their ES5 equivalents. Code transpiled with Babel will usually run quite a bit faster than running ES2015 directly, especially with Babel in loose mode.
https://kpdecker.github.io/six-speed/ is what I based my comment on. It seems to have improved since I last looked and ES6 will probably suffice performance-wise.
Things like destructuring, are still 10x slower in Node 5.8 than through Babel, for example (and even 100x slower in Firefox). The spread parameter is similar. They're both used a lot in modern JS (when using Redux, for example). It's good that there are native implementations now, but both for performance and compatibility most people will/should probably keep transpiling ES6 for now.
> Things like destructuring, are still 10x slower in Node 5.8 than through Babel, for example (and even 100x slower in Firefox). The spread parameter is similar.
That's interesting. I had no idea there was such a drop in performance - orders of magnitude in some engines!
This is an important point. If your usage of these techniques is not on a hot critical path, I think there's much to gain by continuing to use them as the native optimizations continue to improve.
Note that this is comparing whatever Babel does with destructuring to the native implementation, in the same engine.
This means two things:
1) Comparing these numbers across engines is pointless: if engine A runs the Babel code 5x faster than engine B but runs the native code at the same sped as enging B, this table will show engine A with a 5x bigger slowdown over Babel than engine B.
2) To make the comparison at all reasonable, this assumes the Babel implementation is correct per spec.
I can't speak to what Babel is doing here, but simply looking at the tests in https://github.com/kpdecker/six-speed/tree/master/tests/dest... it's clear that the "es5" version and "es6" version are testing different behaviors: the former indexes into the array, while the latter destructures it. Indexing is fundamentally a O(1) operation in array length, while destructuring is O(N) unless you manage to prove quite a lot statically about your operating environment, and they will produce different results in general (though again, if you can prove enough statically about your operating environment you may be able to prove that they are identical). This happens because in ES2015 array destructuring is defined in terms of array iteration, not indexing.
In practice, proving anything statically about JS is a nightmare at best and impossible in pretty much any case of interest, so the best you can do with destructuring is dynamic sanity checks on the hot path...
It's been mentionned already on the thread talking about this benchmark: it's broken and does not give any interesting infos about real life performances (https://news.ycombinator.com/item?id=11203183)
Right, I worded it badly. The performance of ES6 code is more of an issue for people who want to switch from transpilers to running ES6 natively (something that's hard to recommend at this point). ES5 code performing slower because of ES6 features should indeed not happen and be avoided.
For your specific example, probably because the implementation is different.
The most notable difference is that arrow functions do not set the "arguments" variable, but there are other subtleties.
I'm not sure how it is done in V8 and co, but if the code is highly optimized, you might have to rewrite big chunks of it, even for small differences, because your optimizations do not go along with a slightly different implementation, or to avoid painful regressions.
The code in question isn't just a binding, and it will have other differences... The code above is similar to what babel does iirc.
Now, that said there are other differences, such as ensuring that let variables are properly scoped and const doesn't allow reassign... that doesn't even begin with the maps and other new strong types that require additional locking and checks that will be less performant in many scenarios.
It's more about stable software with understandable, manageable code more than it is absolute, raw performance.
This is a case of "make it work right; then make it work fast". ES2015 performance will improve with time (we've already made 8-10x improvements on certain features) [0].
Strong mode work was stopped for a variety of nuanced reasons detailed here [1].
You can see comparisons between ES5 and ES2015 feature equivalents, as well as comparisons with older versions at https://kpdecker.github.io/six-speed/.
It's important to remember that implementation of ES2015 is merely the first pass; optimization comes soon after and will rapidly improve performance. General, absolute numbers (e.g. "ES2015 is X% slower than ES5") are usually either nonspecific or soon out-of-date. The best advice is to revise your performance assumptions frequently based on real code.
r.e. ES5 side-effects: ES2015 adds language features and changes semantics of existing features in ways that necessarily change the execution path of code (including ES5 code). When V8 first tried implemented proper (ES2015) RegExp subclassing, for example, it regressed existing (ES5) RegExp performance by ~70%, but a subsequent optimization reduced the regression to ~9%. This is an unfortunate consequence of a rapidly evolving spec, but these cases are exceptional and will get better over time.
So I'm an above average JS developer. I feel save saying this and claiming this.
I would never use most of the exotic new stuff and I would probably never use any of the red stuff.
I'm not saying it shouldn't be in there. I love that JS can be a fit for everybody. I just wonder how much we're gonna be adding and when it's enough...
While I agree with you I also don't believe in adding things just for the sake of adding features. Remember, once you put a feature in a language it's going to remain in it forever and slowly the language can get bloated with lot of history in it's baggage (not that js already doesn't have this).
Obviously this is true, but I kind of agree with him.
So far I don't use the overwhelming majority of new features and it does sort of seem like JavaScript is in some kind of race with itself to implement every paradigm and idea that anyone latches on to.
There is beauty in simplicity and commonality in code. I don't think there would be anything wrong with taking a more conservative approach to adding new language constructs.
JavaScript needed a class syntax. It needed block-scoped variables. It needed better parameter syntax and object loops. Generators are great. I'm not sure how much else of what is being added is strictly necessary as opposed to a technological debt for the future that must be supported for compatibility.
Although the multitude of awful shims people invented would tend to support my assessment that a singular way of doing things was needed. Oh, and all the blog posts explaining "this" and prototype inheritance..
I take it back, you didn't get me. JavaScript needed a coherent common syntax for doing what everyone was trying to do anyway.
As far as using the new features, how many people actually can/are? I can agree that they're needed, and I'm glad that they're coming, but support in browsers is variable at best, meaning you can't really use it in the front-end for anything in production without a transpiler, which IMHO mostly defeats the purpose. When you try to actually debug something, you have to deal with the mental translation of going back and forth between the translated/compiled stuff that's actually running and the source code.
Could be different for stuff running in Node on the server, but then according to this, Node native support for ES6 features varies between bare-bones and not very tested to nonexistent. So we're back to transpilers again, not quite as much of a pain on the server, but still not great.
Did it really need class syntax? I mean, there are a lot of us following functional patterns as much as possible, and I feel that I rarely need class syntax... I mean it's kind of nice for a react component, but even then, not something that couldn't easily be represented with static objects.
I rarely use classes, or for that matter constructor functions... a lot of the code is far easier to follow and reason that way.
As to block-scoped variables, understanding that variables were scoped to the function they are declared in wasn't a huge hinderance, and is part of the reason why the new stuff runs slower... creating that scope has overhead.
I'll add that destructured assignment and string templates are huge... taking generators the next step to async functions with await is very nice as well, not that co didn't work.
Fat-arrow syntax cuts quite a bit of typing out with a default return.
Each piece is valuable to some, and collectively not everything is valuable to some... Just because you don't see the value, doesn't mean that nobody does.
I, for example, will probably not use the WeakMap/Map/Symbol in practice... But I see how someone can find those valuable additions.
While I hold your same opinion I think you're being down voted for not elaborating on the way as it appears you're only ranting and not adding anything to the conversation.
For me most of my work in node needs to work over multiple versions and most of my browser work also needs to work over multiple browsers. Transpiling with Babel means I can't debug the code I actually wrote (even mappings won't work in all browsers or older ones) and I don't need extra, unnecessary complexity added to my build and development.
I like many of ES6's features but I value simplicity over almost everything so I can only hope to use it at some point in the future.
It doesn't matter if you don't use them, libraries that you might depend on will use them, and you have to know the new syntax in order to read javascript code from now on.
2. Imports, while more ambiguous than `require`, look quite nice:
import React, { Component } from 'react';
import Block from './Block';
vs
var React = require('react');
var Block = require('./Block');
3. Exports are cleaner and streamlined
export default myFunction()
vs
module.exports = myFunction()
So while ES6 is more ambiguous than ES5 and has a higher learning curve, I think it's much cleaner and looks more like a proper programming language. ES5 feels like a homegrown hacky language in comparison.
The code I write in ES2015 makes very heavy use of arrow functions, destructuring parameters, the ellipsis syntax for extending arrays and objects, and the syntax for evaluated object literal keys.
I don’t find the arrow function version of (1) cleaner than the anonymous function version. Is it cleaner because you can fit it on one line?
I don’t find the import version of (2) cleaner than the require() version. Having a boring old function that’s consistent with the rest of the language actually seems better than dedicated syntax, especially when that dedicated syntax is unnecessarily verbose. Copying Python’s might have been okay:
// I have to repeat “fs” =(
var fs = require('fs');
// Wait, I still have to repeat “fs” *and* it’s longer
// *and* it looks more confusing? There’s no precedent
// for this use of * in JavaScript.
import * as fs from 'fs';
// Nice.
import fs;
I don’t find the `export default` version of (3) cleaner or more streamlined than the one that assigns to `module.exports`. It just seems like another waste of dedicated syntax.
There are a lot of one liners that are much more composable in the fat-arrow syntax. The default returns takes a lot of it out, and makes it simpler the simpler it starts.
Beyond this, the above also uses templates, which you can even create custom processors for templates...
var result = await sql`
SELECT *
FROM
a
WHERE
a.foo = ${bar}
`
You can create an sql processor that turns that query as a template into a parameterized query for the database, that returns a promise, which inside an async function can be awaited directly... I wrote a few libraries that did just that to make using sql, bigtable (azure tables), queues and other pieces really easy to use... With that I was able to write data migration scripts with ease... it was really awesome to see.
Your second example is only if there's no default export... the local name doesn't have to match the name of the module, also modules can be `foo.bar` or `foo_bar` or `foo-bar` which can't be a single value within the script... so it creates a disconnect there, requiring the localized in-script name.
> There are a lot of one liners that are much more composable in the fat-arrow syntax. The default returns takes a lot of it out, and makes it simpler the simpler it starts.
They’re not more composable… they’re slightly shorter, and anything non-trivial doesn’t fit on one line. Template literals are nice, sure.
> the local name doesn't have to match the name of the module,
But when it does, everything is a lot more obvious. It works fine for all the Python modules, too.
Try the following without fat-arrow syntax off of an object
{
foo: (a,b) => doFoo(this, a, b, 'fixed-value')
}
I find the fat-arrow syntax allows for much more dynamic flows that are easy to understand, more so than bind, and like the above, where bind wouldn't work.
There's a lot of oneliner possibilities when you get rid of 12+ characters `function(){ return ` ... Also, I find the fat-arrow syntax looks better in a lot of cases, where you might use bind.
I will be pretty happy if I see non-ES6 code if it is properly structured and documented well.
Nevertheless if I see people has just replaced `class` with `jQuery.extend` or with some other helper tool it would be a downside. Also we are talking about lodash vs native implementation.
That's one of the reasons I stopped working with coffeescript.
This doesn't seem like a complete list, what about modules? (I.E. import/export) which is (at least for me) the most interesting thing in es6 that needs to be implemented in node.
Why do you think it's important that they implement import/export? Node already has a module system that works well. Support import/export is much more important in Browsers which has no module system.
Browserify and Webpack bundling seems to work pretty well.
I agree that getting ES6 modules in the browser will be nice, in the end, I see it working in practice a lot like it's implemented in Babel, to work with CJS modules.
>Why do you think it's important that they implement import/export?
For compatibility. Everyone is moving toward ES6 modules, so if you write your app in CommonJS now, you'll likely have to re-factor it into ES6 modules in the future.
Not a deal-breaker, but it's certainly needed (and it sounds like Node devs are well aware of this).
That's true, but more and more code will be written using es6 modules (since people want to write the same code on both the frontend and backend).
But yes, you're correct that it will be years before CommonJS is removed, if ever. Although I could see it being tagged as deprecated in the next few years.
I personally would have been totally fine with CommonJS on the frontend, as a longtime browserify user. Almost wish that had happened simply to avoid the transition to another module system for the Node ecosystem. But es6 modules do have certain advantages for the frontend, like making tree-shaking easy.
Node's module system has numerous drawbacks. It's a clever hack but having a native module system with proper imports and exports, and which is amenable to static analysis is a huge improvement. It's probably been the biggest productivity boon for me of any of the ES6 features.
Typescript treats import and export as first class citizens. When using it in my scripts it pulls in not only the module but also typings for that module as well.
Of course; Typescript compiles in such a way that Node understands what was intended, it would be nice to compile to ES6 directly. Typescript is ES6 with types. A small change, essentially ignoring types, would require so little processing that it could probably be done live as if it were reading pure ES6.
I think that's within the realm of possibility but would require Node to understand ES6 in its entirety.
There's a huge philosophical difference between require and import/include. The main technical difference is that require is scoped! Philosophically require is a object. While import is a bunch of code.
The Node community deliberately do not want code includes. We want you to make reusable modules instead.
Copy all your include files and the include files of your include files into one file. Then you will also see the problem.
Once the browsers (and therefor v8) will implement the module and loader specs, node.js will have import/exports.
Comparability with javascript (and browsers) is more important then the community's dislike of imports (if there is such a thing), so I'm not sure if that is relevant here.
Release a Node.js version 10 with all the backwards stuff removed. Support the current version for LTS duration. Throw in a tool that does a lot of old->new conversion automatically, like the Python 2to3 tool.
Only because they didn't deprecate 2 soon enough, they could have forced peoples hand, we would all have complained but it would be long forgotten by now.
I understand that some of the issue is lazy developers, but I really think that the majority of the problems would be caused by unmaintained code.
Websites frequently sit around un-touched for years, hell our company website has some js code that was written by me over 4 years ago and hasn't been touched since because there's just no need to screw with it. And i'll be honest, it's not going to get updated until something breaks, and I would consider myself someone who likes to be on the cutting edge and is willing to endure breaking changes in more things than i should.
I really think that by advocating for a "good" subset of the language, we can get all of the benefits of removing old stuff with very little of the downsides. Something like "use strict"; in javascript now. It removed many terrible things from the language in a way that you could mix old and new code together and get the benefits of both.
That worked great, and i really think it could work great again. Something like a "use es6" or something that removes a massive set of "bad ideas" in the language, but it does it in a per-file or per-function basis. Allowing new code to be written in a better way, and allows old code to keep going as it was for a very long time.
As someone who dealt extensively with piles of legacy Python 2.7 code, I can wholeheartedly agree with this. If the "forced" 2-3 change would have occurred right away, I am certain my employer (at the time) would have forked Python itself.
> they could have forced peoples hand, we would all have complained but it would be long forgotten by now.
Had they been forced, a significant portion of users would have thought long and hard and jumped ship to a different language altogether, and Python "would be long forgotten by now".
Nodejs is a minor JavaScript runtime, and the backward compatibility is not really an issue:
There is breaking changes in the node standard library from time to time. That's the reason it was forked into io.js last year, and why they now use SemVer.
The real compatibility issue is the web ! I built a small website for an association several years ago, it still works.
What if Google Chrome decided to remove whatever JavaScript features I used at this time ?
>Release a Node.js version 10 with all the backwards stuff removed. Support the current version for LTS duration. Throw in a tool that does a lot of old->new conversion automatically, like the Python 2to3 tool.
I can't help but notice that once again tail call optimization seems to be one of the last things added, and even then requires a specific flag to work.
Is there some reason for this pattern, like actual performance/technical difficulties, or is it more "My Java/C professor said recursion is bad"?
From my understanding, there's not a lot of performance benefit in most cases and a performance degradation in others. Also there's some reluctance to change the behavior of existing code. Plus a whole bunch of unaddressed debugging issues (what does console.stack show?).
For Node.js, define a simple function that does minimal computation, but that would blow the stack if called say a million times[0]. Run that function inside of a new vm context[1]. If it errors with a stack overflow, then no TCO.
Would be great if each section linked to a description of the functionality. This would help new users and those trying to level up skills. Sure you can just Google it, but it would make this chart that much more useful.
Does anyone know if Node.js will have backports for ES6 in version 4.X? Would love to use ES6 in my current project but I don't want to move from Node.js 4.X to 5.
I would assume the answer is no. Backporting ES6 features could introduce some breaking changes. You could transpile your code with something like Babel[1].
It seems crazy to me that performance takes a backseat to syntactical sugar, which is most of what ES6 provides. There are a few new constructs, but in my mind when is it ever acceptable to have performance regressions to make the code look pretty?
And the fact that it isn't optional is alarming. If you use the new features, you should have to suffer performance penalty if there is one, and at least be able to make that design choice and trade-off between "cleaner" or "prettier" code and poor performance.
I don't think you can call something "complete" or green until the performance issue is solved.
It's better to make something that works, and then improve performance as-needed than to try and optimize before hand. You don't always know the real world impact of a given solution until you have one, and synthetic tests aren't a reflection of real world impact.
Beyond this, I happen to like a lot of the sugar. It makes code simpler, cleaner and in most cases easier to comprehend... Sometimes the fat arrow functions returning fat arrow functions gets a little weird, but outside of that, it's a pretty big benefit. Async functions will help a lot as well once they land, for now, Babel works well enough.
It isn't that this new syntax is slow, so much as V8 has a shit-ton of internal machinery dedicated to optimizing specific execution paths, and it is those things which get a massive efficiency boost. In that sense, becoming syntax complete is just a first step down a very long road.
It's not so simple as (paraphrasing) 'ES6 is sugar and makes ES5 regress in speed.' Generally, "make it work right, then make it work fast" is actually a pretty good strategy for implementing new features.
I think it's awesome how well the V8 team is working on these features, and how much more closely the Node core teams are working with the V8 teams. Much better coherence than in the past. (at least from the perspective of a mostly passive observer).
There are a few bits wrt ES2016/2017 that I'm hoping come in before long as well... will be nice to no longer feel the need for babel, at least on the server-side pieces of many projects.
95 comments
[ 4.4 ms ] story [ 167 ms ] threadThings like destructuring, are still 10x slower in Node 5.8 than through Babel, for example (and even 100x slower in Firefox). The spread parameter is similar. They're both used a lot in modern JS (when using Redux, for example). It's good that there are native implementations now, but both for performance and compatibility most people will/should probably keep transpiling ES6 for now.
That's interesting. I had no idea there was such a drop in performance - orders of magnitude in some engines!
This means two things:
1) Comparing these numbers across engines is pointless: if engine A runs the Babel code 5x faster than engine B but runs the native code at the same sped as enging B, this table will show engine A with a 5x bigger slowdown over Babel than engine B.
2) To make the comparison at all reasonable, this assumes the Babel implementation is correct per spec.
I can't speak to what Babel is doing here, but simply looking at the tests in https://github.com/kpdecker/six-speed/tree/master/tests/dest... it's clear that the "es5" version and "es6" version are testing different behaviors: the former indexes into the array, while the latter destructures it. Indexing is fundamentally a O(1) operation in array length, while destructuring is O(N) unless you manage to prove quite a lot statically about your operating environment, and they will produce different results in general (though again, if you can prove enough statically about your operating environment you may be able to prove that they are identical). This happens because in ES2015 array destructuring is defined in terms of array iteration, not indexing.
In practice, proving anything statically about JS is a nightmare at best and impossible in pretty much any case of interest, so the best you can do with destructuring is dynamic sanity checks on the hot path...
See also https://bugzilla.mozilla.org/show_bug.cgi?id=1177319 for some more info, though not much.
The most notable difference is that arrow functions do not set the "arguments" variable, but there are other subtleties.
I'm not sure how it is done in V8 and co, but if the code is highly optimized, you might have to rewrite big chunks of it, even for small differences, because your optimizations do not go along with a slightly different implementation, or to avoid painful regressions.
Now, that said there are other differences, such as ensuring that let variables are properly scoped and const doesn't allow reassign... that doesn't even begin with the maps and other new strong types that require additional locking and checks that will be less performant in many scenarios.
It's more about stable software with understandable, manageable code more than it is absolute, raw performance.
These benchmarks are about the cost of transpilation (where ES6 support is not native).
Strong mode work was stopped for a variety of nuanced reasons detailed here [1].
(Disclaimer: I'm a PM on the V8 team.)
[0]: https://twitter.com/addyosmani/status/699976753255751681 [1]: https://groups.google.com/forum/#!topic/strengthen-js/ojj3TD...
It's important to remember that implementation of ES2015 is merely the first pass; optimization comes soon after and will rapidly improve performance. General, absolute numbers (e.g. "ES2015 is X% slower than ES5") are usually either nonspecific or soon out-of-date. The best advice is to revise your performance assumptions frequently based on real code.
r.e. ES5 side-effects: ES2015 adds language features and changes semantics of existing features in ways that necessarily change the execution path of code (including ES5 code). When V8 first tried implemented proper (ES2015) RegExp subclassing, for example, it regressed existing (ES5) RegExp performance by ~70%, but a subsequent optimization reduced the regression to ~9%. This is an unfortunate consequence of a rapidly evolving spec, but these cases are exceptional and will get better over time.
(Disclaimer: I'm a PM on the V8 team.)
I would never use most of the exotic new stuff and I would probably never use any of the red stuff.
I'm not saying it shouldn't be in there. I love that JS can be a fit for everybody. I just wonder how much we're gonna be adding and when it's enough...
So far I don't use the overwhelming majority of new features and it does sort of seem like JavaScript is in some kind of race with itself to implement every paradigm and idea that anyone latches on to.
There is beauty in simplicity and commonality in code. I don't think there would be anything wrong with taking a more conservative approach to adding new language constructs.
JavaScript needed a class syntax. It needed block-scoped variables. It needed better parameter syntax and object loops. Generators are great. I'm not sure how much else of what is being added is strictly necessary as opposed to a technological debt for the future that must be supported for compatibility.
Did it? Or is that just a paradigm you've latched on to?
Although the multitude of awful shims people invented would tend to support my assessment that a singular way of doing things was needed. Oh, and all the blog posts explaining "this" and prototype inheritance..
I take it back, you didn't get me. JavaScript needed a coherent common syntax for doing what everyone was trying to do anyway.
Could be different for stuff running in Node on the server, but then according to this, Node native support for ES6 features varies between bare-bones and not very tested to nonexistent. So we're back to transpilers again, not quite as much of a pain on the server, but still not great.
I rarely use classes, or for that matter constructor functions... a lot of the code is far easier to follow and reason that way.
As to block-scoped variables, understanding that variables were scoped to the function they are declared in wasn't a huge hinderance, and is part of the reason why the new stuff runs slower... creating that scope has overhead.
I'll add that destructured assignment and string templates are huge... taking generators the next step to async functions with await is very nice as well, not that co didn't work.
Fat-arrow syntax cuts quite a bit of typing out with a default return.
Each piece is valuable to some, and collectively not everything is valuable to some... Just because you don't see the value, doesn't mean that nobody does.
I, for example, will probably not use the WeakMap/Map/Symbol in practice... But I see how someone can find those valuable additions.
> I feel save saying this and claiming this
Is `this` some kind of pun? When I was learning JS I never felt safe around this:)
For me most of my work in node needs to work over multiple versions and most of my browser work also needs to work over multiple browsers. Transpiling with Babel means I can't debug the code I actually wrote (even mappings won't work in all browsers or older ones) and I don't need extra, unnecessary complexity added to my build and development.
I like many of ES6's features but I value simplicity over almost everything so I can only hope to use it at some point in the future.
Are we talking 'does not use many jQuery plugins these days' or 'regular contributor to ${framework}' here?
1. Arrow functions are really handy:
is much cleaner than 2. Imports, while more ambiguous than `require`, look quite nice: vs 3. Exports are cleaner and streamlined vs So while ES6 is more ambiguous than ES5 and has a higher learning curve, I think it's much cleaner and looks more like a proper programming language. ES5 feels like a homegrown hacky language in comparison.Random example:
In classic JavaScript, I'd have to write something like: The new syntax rules combine to significantly improve the clarity of this kind of transformation function.I don’t find the import version of (2) cleaner than the require() version. Having a boring old function that’s consistent with the rest of the language actually seems better than dedicated syntax, especially when that dedicated syntax is unnecessarily verbose. Copying Python’s might have been okay:
I don’t find the `export default` version of (3) cleaner or more streamlined than the one that assigns to `module.exports`. It just seems like another waste of dedicated syntax.Beyond this, the above also uses templates, which you can even create custom processors for templates...
You can create an sql processor that turns that query as a template into a parameterized query for the database, that returns a promise, which inside an async function can be awaited directly... I wrote a few libraries that did just that to make using sql, bigtable (azure tables), queues and other pieces really easy to use... With that I was able to write data migration scripts with ease... it was really awesome to see.Your second example is only if there's no default export... the local name doesn't have to match the name of the module, also modules can be `foo.bar` or `foo_bar` or `foo-bar` which can't be a single value within the script... so it creates a disconnect there, requiring the localized in-script name.
They’re not more composable… they’re slightly shorter, and anything non-trivial doesn’t fit on one line. Template literals are nice, sure.
> the local name doesn't have to match the name of the module,
But when it does, everything is a lot more obvious. It works fine for all the Python modules, too.
There's a lot of oneliner possibilities when you get rid of 12+ characters `function(){ return ` ... Also, I find the fat-arrow syntax looks better in a lot of cases, where you might use bind.
Nevertheless if I see people has just replaced `class` with `jQuery.extend` or with some other helper tool it would be a downside. Also we are talking about lodash vs native implementation.
That's one of the reasons I stopped working with coffeescript.
The rest isn't finished right now.
I agree that getting ES6 modules in the browser will be nice, in the end, I see it working in practice a lot like it's implemented in Babel, to work with CJS modules.
For compatibility. Everyone is moving toward ES6 modules, so if you write your app in CommonJS now, you'll likely have to re-factor it into ES6 modules in the future.
Not a deal-breaker, but it's certainly needed (and it sounds like Node devs are well aware of this).
But yes, you're correct that it will be years before CommonJS is removed, if ever. Although I could see it being tagged as deprecated in the next few years.
I personally would have been totally fine with CommonJS on the frontend, as a longtime browserify user. Almost wish that had happened simply to avoid the transition to another module system for the Node ecosystem. But es6 modules do have certain advantages for the frontend, like making tree-shaking easy.
Of course; Typescript compiles in such a way that Node understands what was intended, it would be nice to compile to ES6 directly. Typescript is ES6 with types. A small change, essentially ignoring types, would require so little processing that it could probably be done live as if it were reading pure ES6.
I think that's within the realm of possibility but would require Node to understand ES6 in its entirety.
The Node community deliberately do not want code includes. We want you to make reusable modules instead.
Copy all your include files and the include files of your include files into one file. Then you will also see the problem.
Comparability with javascript (and browsers) is more important then the community's dislike of imports (if there is such a thing), so I'm not sure if that is relevant here.
Instead they are doing doing the C++/Scala way: with complexity.
Good thing I have Clojurescript...
They can only discourage people to use the old stuff, if a better alternative is now available.
Come on, this is Node.js, not Win98.
I mean it's 8 years later and python is still feeling the issues from the 2->3 change.
I understand that some of the issue is lazy developers, but I really think that the majority of the problems would be caused by unmaintained code.
Websites frequently sit around un-touched for years, hell our company website has some js code that was written by me over 4 years ago and hasn't been touched since because there's just no need to screw with it. And i'll be honest, it's not going to get updated until something breaks, and I would consider myself someone who likes to be on the cutting edge and is willing to endure breaking changes in more things than i should.
I really think that by advocating for a "good" subset of the language, we can get all of the benefits of removing old stuff with very little of the downsides. Something like "use strict"; in javascript now. It removed many terrible things from the language in a way that you could mix old and new code together and get the benefits of both.
That worked great, and i really think it could work great again. Something like a "use es6" or something that removes a massive set of "bad ideas" in the language, but it does it in a per-file or per-function basis. Allowing new code to be written in a better way, and allows old code to keep going as it was for a very long time.
Had they been forced, a significant portion of users would have thought long and hard and jumped ship to a different language altogether, and Python "would be long forgotten by now".
EcmaScript itself has to be backwards compatible or newer browsers could not display older webpages any more which none of the browser vendors want.
There is breaking changes in the node standard library from time to time. That's the reason it was forked into io.js last year, and why they now use SemVer.
The real compatibility issue is the web ! I built a small website for an association several years ago, it still works.
What if Google Chrome decided to remove whatever JavaScript features I used at this time ?
Yeah, because it worked great for Python...
which depends on the JVM ...
ES6 has nothing to do with either C++ or Scala. It takes most of its new syntax from Python.
Which has a mature ecosystem managed by people experienced in maintaining software over a decade or more.
Is there some reason for this pattern, like actual performance/technical difficulties, or is it more "My Java/C professor said recursion is bad"?
https://github.com/tc39/proposal-ptc-syntax
[0] - function n(x){if(x > 0) n(x-1)}
[1] - https://nodejs.org/api/vm.html#vm_vm_runinnewcontext_code_sa...
[1]https://babeljs.io/
And the fact that it isn't optional is alarming. If you use the new features, you should have to suffer performance penalty if there is one, and at least be able to make that design choice and trade-off between "cleaner" or "prettier" code and poor performance.
I don't think you can call something "complete" or green until the performance issue is solved.
Beyond this, I happen to like a lot of the sugar. It makes code simpler, cleaner and in most cases easier to comprehend... Sometimes the fat arrow functions returning fat arrow functions gets a little weird, but outside of that, it's a pretty big benefit. Async functions will help a lot as well once they land, for now, Babel works well enough.
It's not so simple as (paraphrasing) 'ES6 is sugar and makes ES5 regress in speed.' Generally, "make it work right, then make it work fast" is actually a pretty good strategy for implementing new features.
There are a few bits wrt ES2016/2017 that I'm hoping come in before long as well... will be nice to no longer feel the need for babel, at least on the server-side pieces of many projects.