current behavior: Uncaught SyntaxError: Rest element must be last element
wished behavior:
path = ['.', 'a'];
file = 'b.txt';
I understand rest operations can't be randomly in between, or both at the beginning and the end, when it comes to array (while it works perfectly fine with objects spread here or there) ... but what's the rationale to not have spread first?
const [...path, b, c] = './a/b/c.txt'.split('/');
// translates to
const path = './a/b.txt'.split('/');
const c = path.length >= 2 ? path.pop() : void 0;
const b = path.length >= 1 ? path.pop() : void 0;
// results into
path = ['.']
b = 'a';
c = 'b.txt'
thoughts?
P.S. the completition is after the amount of defined parameters after the rest in decreasing order ... so that const [...path, a] = 'a'.split('/') would result in path being an empty array, and a being "a"
// "just go with this instead"
const [file, ...path] = './a/b.txt'.split('/').reverse();
the problem is that the path would be reversed too ... so the split, and the path itself, need double reverse operations ... about perf though ... and syntax, and boilerplate ... no, thanks!
(if we justified Array#reduceRight and friends, this topic is just about the same request)
last update: somebody mentioned a desire for [start, ..._, end] too, which makes my simplification for resolution more convoluted, yet this proposal doesn't strictly prevent JS to be like Python in the future:
Given that any use of rest syntax here causes the entire iterator to be exhausted, I agree with you that a single rest param seems like it should be permitted in any position of the array.
I'm not sure if there's other barriers to doing so, though, nor am I aware of why this restriction in ES2015 is present in the first place.
glad we agree there's hope to improve the current state ... to complete the idea with possible ...rest in between (Python rightly throws if more than a rest exist in the pattern):
const [a, b, ..._, c, d] = 'a/b/not/relevant/c/d'.split('/');
// translates to
const _ = 'a/b/not/relevant/c/d'.split('/');
// prefixes
const a = _.length ? _.shift() : void 0;
const b = _.length ? _.shift() : void 0;
// suffixes
let after = 2;
const d = _.length >= after-- ? _.pop() : void 0;
const c = _.length >= after-- ? _.pop() : void 0;
// results into
a = 'a'
b = 'b'
_ = ['not', 'relevant']
c = 'c'
d = 'd'
This is a mocked logic that should always produce expected behavior
another way to think about it as interpreter/engine resolution:
const [a, b, ..._, c, d] = 'a/b/not/relevant/c/d'.split('/');
// translates to
const _ = 'a/b/not/relevant/c/d'.split('/');
// to be destructured as [a, b, _, c, d]
const result = [];
// interpreter
let before = 2;
let after = 2;
// prefix
while (before--)
result.push(_.shift());
// intermediate
result.push(_);
// suffix
while (after--) {
if (_.length > after)
result.push(_.pop());
}
// test
console.log(result);