V8 crankshaft vs. arguments object
mrale.ph
mrale.ph
Off topic: The design decision in ES2015 to have lexical `arguments` [1] in arrow functions completely baffled me and my coworkers. It completely breaks the contract that most people think arrow functions abide by, which is that it's a simple transformation to `function() { ... }.bind(this)`.
function foo() {
const bar = (a, b, c) => {
console.log([a, b, c]);
console.log(arguments);
};
bar('a', 'b', 'c');
}
> foo('x', 'y', 'z');
['a', 'b', 'c']
{ '0': 'x', '1': 'y', '2': 'z' }
In realistic cases it's common to switch to arrow functions just for their brevity or to capture `this` – and then all of a sudden things aren't doing what you expect. This has already bitten me several times.[1] https://developer.mozilla.org/en-US/docs/Web/JavaScript/Refe...
There is really no need for the arguments object in a world with default and rest parameters, and it has always been an obstacle to performance, so I'm glad arrow functions don't use it.
Also, changing that example to use rest parameters:
function foo() {
const bar = (...abc) => {
console.log(abc);
console.log(arguments);
};
bar('a', 'b', 'c');
}
SyntaxError: 'arguments' object may not be used in conjunction with a rest parameter
...which, okay, hmmm, it's sort of attempting to help me avoid confusion here. But that...was not what I was expecting. It's really weird that all of a sudden, just by adding a rest parameter to my function, a reference to `arguments` becomes invalid syntax. foo(1, 2, 3)
// ["a", "b", "c"]
// [1, 2, 3]
And this is what I get from https://babel.io/repl : 'use strict';
function foo() {
var _arguments = arguments;
var bar = function bar() {
for (var _len = arguments.length, abc = Array(_len), _key = 0; _key < _len; _key++) {
abc[_key] = arguments[_key];
}
console.log(abc);
console.log(_arguments);
};
bar('a', 'b', 'c');
}A method could be deoptimised once early, but then not again when the program is actually running in your inner loop. In which case you don't care it was deoptimised.
In the optimising implementation of Ruby I work on, we are aggressive about splitting (multiple versions of a method so they can collect independent profiling data) and that means one version of a method may be deoptimised, but others aren't. How do you show that when you are looking at a single copy of the source code?
Not having `arguments` isn't a mistake because `...rest` parameters are allowed and are much better in every way.
...arguments object not being an Array is yet another
JavaScript wart that causes nothing but special cases
and complexity in optimization pipelines...
So, why can't we make `arguments` into an immutable Array for ES7? Is there any compiler advantage to keeping the special case?While it would be nice to require everyone to re-write their website code, the cost would probably be in the hundreds of billions of dollars. The pragmatic choice is to leave it in place and discourage it's use. Maybe it can be deprecated in a couple decades.