guest271314 at gmail.com (2019-06-07T01:28:53.901Z)
> I've run into a couple cases now where it'd be convenient to use a rest operator at the beginning or middle of an array destructuring, as in:
>
> ```const [...xs, y] = someArray;```
>
> The semantics would be simple: exhaust the iterable to create the array of ```xs```, like a standard rest operator would do, but then slice off the last item and put it in ```y```.
```const [[...xs], y = xs.pop()] = [someArray];```
or
```
let condition = "b";
const [[...xs], [y] = xs.splice(xs.findIndex(v => v === condition), 1)] = [someArray];
```
> For example, I was working with some variable argument functions that, in FP style, always take their data last. So I had a function like this:
>
>```
> function match(...matchersAndData) {
> const matchers = matchersAndData.slice(0, -1);
> const data = matchersAndData[matchersAndData.length - 1];
> // do matching against data
> }
>```
> Under this proposal, the above could be rewritten:
>
> ```function reduce(...matchers, data) { /* ... */ }```
A similar pattern can be applied at function arguments scope by dynamically setting default parameter
```
function match(matchers, data = matchers.pop()) {
console.log(matchers, data);
}
match(`/a/ /b/ /c/ data`.split` `)
```
Can you describe the difference between ```pad``` function and ```match``` function?
--
If gather ```pad``` function accurately you can use object destructuring with default parameters, see https://stackoverflow.com/a/43637164
```
function pad({targetLength = 1, opts = [], paddingChar = opts.length ? opts.shift() : " ", data = void 0} = {}) {
console.log(targetLength, paddingChar, opts, data);
}
pad({opts:` /a/ /b/ /c/`.split(/\s(?!\s)/)})
```
guest271314 at gmail.com (2019-06-07T01:09:22.250Z)
> I've run into a couple cases now where it'd be convenient to use a rest operator at the beginning or middle of an array destructuring, as in:
>
> ```const [...xs, y] = someArray;```
>
> The semantics would be simple: exhaust the iterable to create the array of ```xs```, like a standard rest operator would do, but then slice off the last item and put it in ```y```.
```const [[...xs], y = xs.pop()] = [someArray];```
> For example, I was working with some variable argument functions that, in FP style, always take their data last. So I had a function like this:
>
>```
> function match(...matchersAndData) {
> const matchers = matchersAndData.slice(0, -1);
> const data = matchersAndData[matchersAndData.length - 1];
> // do matching against data
> }
>```
> Under this proposal, the above could be rewritten:
>
> ```function reduce(...matchers, data) { /* ... */ }```
A similar pattern can be applied at function arguments scope by dynamically setting default parameter
```
function match(matchers, data = matchers.pop()) {
console.log(matchers, data);
}
match(`/a/ /b/ /c/ data`.split` `)
```
Can you describe the difference between ```pad``` function and ```match``` function?
--
If gather ```pad``` function accurately you can use object destructuring with default parameters, see https://stackoverflow.com/a/43637164
```
function pad({targetLength = 1, opts = [], paddingChar = opts.length ? opts.shift() : " ", data = void 0} = {}) {
console.log(targetLength, paddingChar, opts, data);
}
pad({opts:` /a/ /b/ /c/`.split(/\s(?!\s)/)})
```
guest271314 at gmail.com (2019-06-07T01:06:04.642Z)
> I've run into a couple cases now where it'd be convenient to use a rest operator at the beginning or middle of an array destructuring, as in:
>
> ```const [...xs, y] = someArray;```
>
> The semantics would be simple: exhaust the iterable to create the array of ```xs```, like a standard rest operator would do, but then slice off the last item and put it in ```y```.
```const [[...xs], y = xs.pop()] = [someArray];```
> For example, I was working with some variable argument functions that, in FP style, always take their data last. So I had a function like this:
>
>```
> function match(...matchersAndData) {
> const matchers = matchersAndData.slice(0, -1);
> const data = matchersAndData[matchersAndData.length - 1];
> // do matching against data
> }
>```
> Under this proposal, the above could be rewritten:
>
> ```function reduce(...matchers, data) { /* ... */ }```
A similar pattern can be applied at function arguments scope by dynamically setting default parameter
```
function match(matchers, data = matchers.pop()) {
console.log(matchers, data);
}
match(`/a/ /b/ /c/ data`.split` `)
```
Can you describe the difference between ```pad``` function and ```match``` function?
--
If gather ```pad``` function accurately you can use object destructuring with default parameters, see https://stackoverflow.com/a/43637164
```
function pad({targetLength = 1, opts = [], paddingChar = opts.length ? opts.shift() : " ", data = void 0} = {}) {
console.log(targetLength, paddingChar, opts, data);
}
pad({opts:` /a/ /b/ /c/`.split(/\s(?!\s)/)})
```
--
Note, technically, it is also possible to set default parameters (e.g., ```paddingChar```) that remain set until explicitly changed, which allow passing _N_ variables to a function which each are defined as a property of an object within a function scope, e.g.,
```
const fn = ((...opts) => ({a:1,b:2,c:3, ...opts.pop()}));
let opts = fn();
console.log(opts);
opts = fn({b: 7});
console.log(opts);
opts = fn({g: 9, x: 10});
console.log(opts);
// and
const fn = ((...opts) => Object.assign({a:1,b:2,c:3}, ...opts.map((prop, index) =>
prop && typeof prop === "object" && !Array.isArray(prop)
? prop
: {[index]:prop}))
);
let opts = fn([2,3], ...[44, "a", {b:7}, {g:8, z: 9}, null, void 0]);
console.log(opts);
```
guest271314 at gmail.com (2019-06-07T00:55:36.756Z)
> I've run into a couple cases now where it'd be convenient to use a rest operator at the beginning or middle of an array destructuring, as in:
>
> ```const [...xs, y] = someArray;```
>
> The semantics would be simple: exhaust the iterable to create the array of ```xs```, like a standard rest operator would do, but then slice off the last item and put it in ```y```.
```const [[...xs], y = xs.pop()] = [someArray];```
> For example, I was working with some variable argument functions that, in FP style, always take their data last. So I had a function like this:
>
>```
> function match(...matchersAndData) {
> const matchers = matchersAndData.slice(0, -1);
> const data = matchersAndData[matchersAndData.length - 1];
> // do matching against data
> }
>```
> Under this proposal, the above could be rewritten:
>
> ```function reduce(...matchers, data) { /* ... */ }```
A similar pattern can be applied at function arguments scope by dynamically setting default parameter
```
function match(matchers, data = matchers.pop()) {
console.log(matchers, data);
}
match(`/a/ /b/ /c/ data`.split` `)
```
Can you describe the difference between ```pad``` function and ```match``` function?
--
If gather ```pad``` function accurately you can use object destructuring with default parameters
```
function pad({targetLength = 1, opts = [], paddingChar = opts.length ? opts.shift() : " ", data = void 0} = {}) {
console.log(targetLength, paddingChar, opts, data);
}
pad({opts:` /a/ /b/ /c/`.split(/\s(?!\s)/)})
```
guest271314 at gmail.com (2019-06-07T00:19:26.843Z)
> I've run into a couple cases now where it'd be convenient to use a rest operator at the beginning or middle of an array destructuring, as in:
>
> ```const [...xs, y] = someArray;```
>
> The semantics would be simple: exhaust the iterable to create the array of ```xs```, like a standard rest operator would do, but then slice off the last item and put it in ```y```.
```const [[...xs], y = xs.pop()] = [someArray];```
> For example, I was working with some variable argument functions that, in FP style, always take their data last. So I had a function like this:
>
>```
> function match(...matchersAndData) {
> const matchers = matchersAndData.slice(0, -1);
> const data = matchersAndData[matchersAndData.length - 1];
> // do matching against data
> }
>```
> Under this proposal, the above could be rewritten:
>
> ```function reduce(...matchers, data) { /* ... */ }```
A similar pattern can be applied at function arguments scope by dynamically setting default parameter
```
function match(matchers, data = matchers.pop()) {
console.log(matchers, data);
}
match(`/a/ /b/ /c/ data`.split` `)
```
Can you describe the difference between ```pad``` function and ```match``` function?
guest271314 at gmail.com (2019-06-07T00:17:00.933Z)
> I've run into a couple cases now where it'd be convenient to use a rest operator at the beginning or middle of an array destructuring, as in:
>
> ```const [...xs, y] = someArray;```
>
> The semantics would be simple: exhaust the iterable to create the array of ```xs```, like a standard rest operator would do, but then slice off the last item and put it in ```y```.
```
const [xs,y] = [...function*(arr) {let [o, len, i] = [[], arr.length, 0]; for (; i < len -1; i++) o[i] = arr[i]; yield* [o, arr[len-1]]}(someArray)];
```
or
```const [[...xs], y = xs.pop()] = [someArray];```
> For example, I was working with some variable argument functions that, in FP style, always take their data last. So I had a function like this:
>
>```
> function match(...matchersAndData) {
> const matchers = matchersAndData.slice(0, -1);
> const data = matchersAndData[matchersAndData.length - 1];
> // do matching against data
> }
>```
> Under this proposal, the above could be rewritten:
>
> ```function reduce(...matchers, data) { /* ... */ }```
A similar pattern can be applied at function arguments scope by dynamically setting default parameter
```
function match(matchers, data = matchers.pop()) {
console.log(matchers, data);
}
match(`/a/ /b/ /c/ data`.split` `)
```
Can you describe the difference between ```pad``` function and ```match``` function?
guest271314 at gmail.com (2019-06-06T21:24:28.832Z)
> I've run into a couple cases now where it'd be convenient to use a rest operator at the beginning or middle of an array destructuring, as in:
>
> ```const [...xs, y] = someArray;```
>
> The semantics would be simple: exhaust the iterable to create the array of ```xs```, like a standard rest operator would do, but then slice off the last item and put it in ```y```.
```
const [xs,y] = [...function*(arr) {let [o, len, i] = [[], arr.length, 0]; for (; i < len -1; i++) o[i] = arr[i]; yield* [o, arr[len-1]]}(someArray)];
```
or
```const [[,...xs], {[someArray.length-1]:y} = someArray] = [someArray];```
or
```const [[...xs], y = xs.pop()] = [someArray];```
> For example, I was working with some variable argument functions that, in FP style, always take their data last. So I had a function like this:
>
>```
> function match(...matchersAndData) {
> const matchers = matchersAndData.slice(0, -1);
> const data = matchersAndData[matchersAndData.length - 1];
> // do matching against data
> }
>```
> Under this proposal, the above could be rewritten:
>
> ```function reduce(...matchers, data) { /* ... */ }```
A similar pattern can be applied at function arguments scope by dynamically setting default parameter
```
function match(matchers, data = matchers.pop()) {
console.log(matchers, data);
}
match(`/a/ /b/ /c/ data`.split` `)
```
Can you describe the difference between ```pad``` function and ```match``` function?
guest271314 at gmail.com (2019-06-06T19:55:21.836Z)
> I've run into a couple cases now where it'd be convenient to use a rest operator at the beginning or middle of an array destructuring, as in:
>
> ```const [...xs, y] = someArray;```
>
> The semantics would be simple: exhaust the iterable to create the array of ```xs```, like a standard rest operator would do, but then slice off the last item and put it in ```y```.
```
const [xs,y] = [...function*(arr) {let [o, len, i] = [[], arr.length, 0]; for (; i < len -1; i++) o[i] = arr[i]; yield* [o, arr[len-1]]}(someArray)];
```
or
```const [[,...xs], {[someArray.length-1]:y} = someArray] = [someArray];```
or
```const [[...xs], y = xs.pop()] = [someArray];```
> For example, I was working with some variable argument functions that, in FP style, always take their data last. So I had a function like this:
>
>```
> function match(...matchersAndData) {
> const matchers = matchersAndData.slice(0, -1);
> const data = matchersAndData[matchersAndData.length - 1];
> // do matching against data
> }
>```
> Under this proposal, the above could be rewritten:
>
> ```function reduce(...matchers, data) { /* ... */ }```
A similar pattern can be applied at function arguments scope by dynamically setting default parameter
```
function match([...matchers], data = matchers.pop()) {
console.log(matchers, data);
}
match(`/a/ /b/ /c/ data`.split` `)
```
Can you describe the difference between ```pad``` function and ```match``` function?
guest271314 at gmail.com (2019-06-06T19:47:51.614Z)
> I've run into a couple cases now where it'd be convenient to use a rest operator at the beginning or middle of an array destructuring, as in:
>
> ```const [...xs, y] = someArray;```
>
> The semantics would be simple: exhaust the iterable to create the array of ```xs```, like a standard rest operator would do, but then slice off the last item and put it in ```y```.
```const [[,...xs], {[someArray.length-1]:y} = someArray] = [someArray];```
or
```const [[...xs], y = xs.pop()] = [someArray];```
> For example, I was working with some variable argument functions that, in FP style, always take their data last. So I had a function like this:
>
>```
> function match(...matchersAndData) {
> const matchers = matchersAndData.slice(0, -1);
> const data = matchersAndData[matchersAndData.length - 1];
> // do matching against data
> }
>```
> Under this proposal, the above could be rewritten:
>
> ```function reduce(...matchers, data) { /* ... */ }```
A similar pattern can be applied at function arguments scope by dynamically setting default parameter
```
function match([...matchers], data = matchers.pop()) {
console.log(matchers, data);
}
match(`/a/ /b/ /c/ data`.split` `)
```
Can you describe the difference between ```pad``` function and ```match``` function?
guest271314 at gmail.com (2019-06-06T19:45:11.488Z)
> I've run into a couple cases now where it'd be convenient to use a rest operator at the beginning or middle of an array destructuring, as in:
>
> ```const [...xs, y] = someArray;```
>
> The semantics would be simple: exhaust the iterable to create the array of ```xs```, like a standard rest operator would do, but then slice off the last item and put it in ```y```.
```const [[,...xs], {[someArray.length-1]:y} = someArray] = [someArray];```
or
```const [[...xs], y = xs.pop()] = [someArray];```
> For example, I was working with some variable argument functions that, in FP style, always take their data last. So I had a function like this:
>
>```
> function match(...matchersAndData) {
> const matchers = matchersAndData.slice(0, -1);
> const data = matchersAndData[matchersAndData.length - 1];
> // do matching against data
> }
>```
> Under this proposal, the above could be rewritten:
>
> ```function reduce(...matchers, data) { /* ... */ }```
A similar pattern can be applied at function arguments scope by dynamically setting default parameter
```
function match([...matchers], data = matchers.pop()) {
console.log(matchers, data);
}
match(`/a/ /b/ /c/ data`.split` `)
```
guest271314 at gmail.com (2019-06-06T19:40:35.818Z)
> I've run into a couple cases now where it'd be convenient to use a rest operator at the beginning or middle of an array destructuring, as in:
>
> ```const [...xs, y] = someArray;```
>
> The semantics would be simple: exhaust the iterable to create the array of ```xs```, like a standard rest operator would do, but then slice off the last item and put it in ```y```.
```const [[,...xs], {[someArray.length-1]:y} = someArray] = [someArray];```
or
```const [[...xs], y = xs.pop()] = [someArray];```
> For example, I was working with some variable argument functions that, in FP style, always take their data last. So I had a function like this:
>
>```
> function match(...matchersAndData) {
> const matchers = matchersAndData.slice(0, -1);
> const data = matchersAndData[matchersAndData.length - 1];
> // do matching against data
> }
>```
> Under this proposal, the above could be rewritten:
>
> ```function reduce(...matchers, data) { /* ... */ }```
A similar pattern can be applied at function arguments scope
```
function match([...matchers], data = matchers.pop()) {
console.log(matchers, data);
}
match(`/a/ /b/ /c/ data`.split` `)
```
guest271314 at gmail.com (2019-06-06T19:37:12.541Z)
> I've run into a couple cases now where it'd be convenient to use a rest operator at the beginning or middle of an array destructuring, as in:
>
> ```const [...xs, y] = someArray;```
>
> The semantics would be simple: exhaust the iterable to create the array of ```xs```, like a standard rest operator would do, but then slice off the last item and put it in ```y```.
```const [[,...xs], {[someArray.length-1]:y} = someArray] = [someArray];```
or
```const [[...xs], y = xs.pop()] = [someArray];```
guest271314 at gmail.com (2019-06-06T19:34:58.710Z)
> I've run into a couple cases now where it'd be convenient to use a rest operator at the beginning or middle of an array destructuring, as in:
>
> ```const [...xs, y] = someArray;```
>
> The semantics would be simple: exhaust the iterable to create the array of ```xs```, like a standard rest operator would do, but then slice off the last item and put it in ```y```.
```const [[,...xs], {[someArray.length-1]:y} = someArray] = [someArray];```
or
```const [[...xs], y = xs.pop()] = [someArray];```
guest271314 at gmail.com (2019-06-06T19:34:29.364Z)
> I've run into a couple cases now where it'd be convenient to use a rest operator at the beginning or middle of an array destructuring, as in:
>
> ```const [...xs, y] = someArray;```
```const [[,...xs], {[someArray.length-1]:y} = someArray] = [someArray];```
or
```const [[...xs], y = xs.pop()] = [someArray];```
guest271314 at gmail.com (2019-06-06T19:29:05.958Z)
```const [[,...xs], {[someArray.length-1]:y} = someArray] = [someArray];```
or
```const [[...xs], y = xs.pop()] = [someArray];```
guest271314 at gmail.com (2019-06-06T17:39:36.823Z)
```const [[...xs],] = someArray;```
```function pad(targetLength, [...opts], data) {console.log(targetLength, opts, data)}```
which is the same as
```function pad(targetLength, opts /* array */, data) {console.log(targetLength, opts, data)}```
guest271314 at gmail.com (2019-06-06T17:30:30.993Z)
```const [[...xs],] = someArray;```
```function pad(targetLength, [...opts], data) {console.log(targetLength, opts, data)}```
```const [[...xs],] = someArray;``` On Thu, Jun 6, 2019 at 4:54 PM Ethan Resnick <ethan.resnick at gmail.com> wrote: > Long-time mostly-lurker on here. I deeply appreciate all the hard work > that folks here put into JS. > > I've run into a couple cases now where it'd be convenient to use a rest > operator at the beginning or middle of an array destructuring, as in: > > ``` > const [...xs, y] = someArray; > ``` > > Or, similarly, in function signatures: > > ``` > function(...xs, y) { } > ``` > > The semantics would be simple: exhaust the iterable to create the array of > `xs`, like a standard rest operator would do, but then slice off the last > item and put it in `y`. > > For example, I was working with some variable argument functions that, in > FP style, always take their data last. So I had a function like this: > > ``` > function match(...matchersAndData) { > const matchers = matchersAndData.slice(0, -1); > const data = matchersAndData[matchersAndData.length - 1]; > // do matching against data > } > ``` > > Under this proposal, the above could be rewritten: > > ``` > function reduce(...matchers, data) { /* ... */ } > ``` > > Another example: a function `pad`, which takes a target length and a > string to pad, with an optional padding character argument in between: > > ``` > function pad(targetLength, ...paddingCharAndOrData) { > const [paddingChar = " "] = paddingCharAndOrData.slice(0, -1); > const data = paddingCharAndOrData[paddingCharAndOrData.length - 1]; > > // pad data with paddingChar to targetLength; > } > ``` > > With this proposal, that could be rewritten: > > ``` > function pad(targetLength, ...opts, data) { > const [paddingChar = " "] = opts; > // pad data with paddingChar to targetLength; > } > ``` > > I'm curious if this has been considered before, and what people think of > the idea. > > Obviously, if `...a` appeared at the beginning or middle of a list, there > would have to be a fixed number of items following it, so a subsequent rest > operator in the same list would not be allowed. > > Thanks > > _______________________________________________ > es-discuss mailing list > es-discuss at mozilla.org > https://mail.mozilla.org/listinfo/es-discuss > -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://mail.mozilla.org/pipermail/es-discuss/attachments/20190606/50c36221/attachment-0001.html>