<div dir="ltr"><div dir="ltr"><div>-1 for maintainability and debuggability<br></div><div><br></div><div>1. maintainability</div><div>if you want to extend the function with additional args,</div><div>then you'll have to retroactively modify all existing calls to avoid off-by-one argcount:</div><div><br class="gmail-Apple-interchange-newline"></div><div>```js</div><div><font face="courier new, monospace">// if extending function with additional args</font></div><div><font face="courier new, monospace">function pad(targetLength, ...opts, data) -> <br></font></div><div><font face="courier new, monospace">function pad(targetLength, ...opts, data, <font color="#ff0000">meta</font>)<br></font></div><div><font face="courier new, monospace"><br></font></div><div><font face="courier new, monospace">// then must retroactively append null/undefined to all existing calls</font></div><div><div><font face="courier new, monospace">pad(1, opt1, opt2, "data") -></font></div><div><font face="courier new, monospace">pad(1, opt1, opt2, "data", <font color="#ff0000" style="">null</font>)</font></div></div><div>```</div><div><br></div><div><br></div><div><br></div><div>2. debuggability</div><div>when debugging, it takes longer for human to figure out which arg is what:</div><div><br></div><div>```js</div><div><span style="font-family:"courier new",monospace">// function pad(targetLength, <font color="#ff0000">...opts</font>, data)</span></div><div><span style="font-family:"courier new",monospace">pad(aa, <font color="#ff0000">bb, cc</font>, dd);</span><br></div><div><font face="courier new, monospace">pad(aa, <font color="#ff0000">bb, cc, dd</font>, ee);<br></font></div><div><font face="courier new, monospace"><br></font></div><div><font face="courier new, monospace">// vs</font></div><div><font face="courier new, monospace"><br></font></div><div><div><span style="font-family:"courier new",monospace">// function pad(targetLength, <font color="#ff0000">opts</font>, data)</span></div></div><div><font face="courier new, monospace">pad(aa, <font color="#ff0000">[bb, cc]</font>, dd);</font></div><div><font face="courier new, monospace">pad(aa, <font color="#ff0000">[bb, cc, dd]</font>, ee);</font></div><div>```<br></div><div><br></div><div><br></div><div><br></div></div><div class="gmail_quote"><div dir="ltr" class="gmail_attr">On Thu, Jun 6, 2019 at 11:54 AM Ethan Resnick <<a href="mailto:ethan.resnick@gmail.com">ethan.resnick@gmail.com</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div dir="ltr"><div>Long-time mostly-lurker on here. I deeply appreciate all the hard work that folks here put into JS.</div><div><br></div>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:<div><br></div><div>```</div><div>const [...xs, y] = someArray;</div><div>```</div><div><br></div><div>Or, similarly, in function signatures:</div><div><br></div><div>```</div><div>function(...xs, y) { }</div><div>```</div><div><br></div><div>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`.</div><div><br></div><div>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:</div><div><br></div><div>```</div><div>function match(...matchersAndData) {</div>  const matchers = matchersAndData.slice(0, -1);<div>  const data = matchersAndData[matchersAndData.length - 1];<br></div>  // do matching against data<div><div>}</div><div>```</div><div><br></div><div>Under this proposal, the above could be rewritten:</div><div><div><br class="gmail-m_2076077158802553250gmail-Apple-interchange-newline">```</div><div>function reduce(...matchers, data) { /* ... */ }</div><div>```</div></div></div><div><br></div><div>Another example: a function `pad`, which takes a target length and a string to pad, with an optional padding character argument in between:</div><div><br></div><div>```</div><div>function pad(targetLength, ...paddingCharAndOrData) {</div><div>  const [paddingChar = " "] = paddingCharAndOrData.slice(0, -1);</div><div>  const data = paddingCharAndOrData[paddingCharAndOrData.length - 1];</div><div>   </div><div>  // pad data with paddingChar to targetLength;</div><div>}</div><div>```</div><div><br></div><div>With this proposal, that could be rewritten:</div><div><br></div><div>```</div><div><div>function pad(targetLength, ...opts, data) {</div><div>  const [paddingChar = " "] = opts;</div><div>  // pad data with paddingChar to targetLength;</div><div>}</div></div><div>```</div><div><br></div><div>I'm curious if this has been considered before, and what people think of the idea.</div><div><br></div><div>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.</div><div><br></div><div>Thanks</div><div><br></div></div>
_______________________________________________<br>
es-discuss mailing list<br>
<a href="mailto:es-discuss@mozilla.org" target="_blank">es-discuss@mozilla.org</a><br>
<a href="https://mail.mozilla.org/listinfo/es-discuss" rel="noreferrer" target="_blank">https://mail.mozilla.org/listinfo/es-discuss</a><br>
</blockquote></div></div>