guest271314 (2019-06-06T17:28:21.000Z)
```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>
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)}```