On Oct 3, 2011, at 6:49 AM, Sean Eagan wrote:

> So I realized hole preservation is actually relevant in both array
> structuring and destructuring.  Array structuring and destructuring
> ellipses forms are both specified in the draft spec to preserve holes.
> 
> Argument lists are merely array structuring patterns, and parameter
> lists are merely array destructuring patterns, so to me, their syntax
> and semantics should be the same.

This is your assertion, but it is debatable whether it is correct or desirable. 
 In the evolution of the ES language, argument lists predates the existence of 
destructuring.  In the legacy language neither the syntactic or applicative 
(apply function) support holes. In addition, the specification of the semantics 
of function invocation made no allowance for the possibility of holes in an 
argument list. So your assertion, to be considered true, requires several 
changes in the existing language semantics (and arguably the syntax of argument 
lists.

One concern that I've already mentioned is that recognizing holes in spread 
would create an inconsistency with the existing semantics of apply and that 
changing apply would be a breaking change that might impact existing code.

We also need to look at the interaction with default argument values:

function f(...argsf) {
   g(...argsf);
   g(argsf[0],argsf[1]);
}
function g(a='a', b='b') {console.log(a+" "+b)}

as currently specified:
   f(...[,1]);
outputs "undefined 1", "undefined 1".  With hole preservation it would output 
"a 1",  "undefined 1".

It seems undesirable that two such calls to g would yield different results.  
Also as currently specified, if a format parameter is assigned its default 
value then it is guaranteed that all formals to its right will also be assigned 
their default value.  This seems like a useful invariant which, as shown above, 
is lost if holes are preserved in this manner.

I think I understand the logic of your position, but I don't think there are 
other factors to consider that make your conclusion less clear cut.


Allen


>  Thus, ellipses forms for argument
> lists and parameter lists should be hole preserving as with array
> structuring / destructuring.  Take this example:
> 
> // rest has 98 holes
> [a, b, ...rest] = [...Array(100)];
> 
> // extract into function form ->
> 
> // rest should still have 98 holes, not 98 undefined's
> (function(a, b, ...rest){})(...Array(100));
> 
> On Fri, Sep 30, 2011 at 8:41 AM, Sean Eagan <[email protected]> wrote:
>> On Thu, Sep 29, 2011 at 2:53 PM, Allen Wirfs-Brock
>> <[email protected]> wrote:
>>> It seems highly desirable that we preserve the existing semantics of 
>>> arguments
>> 
>> I agree, for backward compatability.
>> 
>>> and that:
>>>    function foo(...args) {
>>>       assert(length.arguments === length.args};
>>>       for (let i in arguments) assert(arguments.hasOwnProperty(i) ===
>>> args.hasOwnProperty(i) && arguments[i] === args[i]);
>>>    }
>> 
>> I disagree, rest parameters are intended as an eventual permanent
>> replacement for `arguments`, and thus it is more important to make
>> them have the correct and consistent with array literal spread element
>> hole preservation behavior, than consistency with what will be the
>> legacy `arguments` to aid a one time migration to rest parameters.  To
>> illustrate the problems I see with filling holes in rest parameters,
>> assume we are working with a holey array:
>> 
>> let holeyArray = [];
>> holeyArray[99] = true;
>> 
>> and some code which uses it:
>> 
>> let spreadTarget = [a, ...holeyArray, b]; // 99 holes
>> holeyArray.forEach(expensiveOperation); // 1 iteration
>> 
>> at some point we decide to abstract this code into functions:
>> 
>> function f(...arr) {
>>  return [a, b, ...arr];
>> }
>> function g(...arr) {
>>  arr.forEach(foo); // holes now filled leading to extra iterations
>> }
>> ...
>> let spreadTarget = f(...holeyArray); // 99 unwanted `undefined`s now
>> g(...holeyArray); // 100 iterations now
>> 
>> 
>>> regardless of how foo was called.  In other words,  baz(...bar) and
>>> baz.apply(undefined,bar) should always produce the same effect.
>> 
>> I agree since one form is not intended to replace the other.  The
>> effect IMHO should be that if baz uses `arguments`, holes are not
>> preserved for backward compatability, but if baz has upgraded to rest
>> parameters, then holes are preserved.
>> 
>> 
>> Also, I think not filling holes can be optimized since the `undefined`
>> values don't need to be added to the rest parameter argument.
>> 
>> Thanks,
>> Sean Eagan
>> 
> 
> Thanks,
> Sean Eagan
> 

_______________________________________________
es-discuss mailing list
[email protected]
https://mail.mozilla.org/listinfo/es-discuss

Reply via email to