On Mon, Oct 3, 2011 at 11:31 AM, Allen Wirfs-Brock
<[email protected]> wrote:
>
> 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.

Sorry, I should have said "should merely be" rather than "are merely".

> 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.

apply supports holes...

f.apply(Array(5));

syntactic calls will support holes...

f(...Array(5))

What *doesn't* support holes is the `arguments` object which is on its way out.

> In addition, the specification of the semantics of function invocation made 
> no allowance for the possibility of holes in an argument list.

The specification of `arguments` dictates this, not function
invocation as a whole.

> So your assertion, to be considered true, requires several changes in the 
> existing language semantics (and arguably the syntax of argument lists.

My assertion is that argument/parameter lists and array
{de}structuring should have as much as possible the same syntax and
semantics, considering that currently as far as i know:

* the only syntactic difference is that array {de}structuring supports
Elision, e.g. [,,,]
* the only semantic difference is that array {de}structuring supports
hole preservation
* i.e.     the only difference is that array {de}structuring supports holes

What about holes makes them applicable to arrays in general but not
argument arrays ?  Everything else in ES.next points to reification of
arguments as plain old arrays, why be different here ?

I would actually be ok with or without both Elision syntax and hole
preservation in ES.next, I just want consistency.

> 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.

apply does not have existing semantics for rest parameters since they
don't yet exist, I'm not suggesting to change the semantics for
`arguments` while it's still around

>
> 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.

Holes would not need to trigger default values.  I was only suggesting
holes be preserved in rest parameters to match array {de}structuring
behavior.  The more important thing to me is that the behavior matches
array destructuring which as currently specified has the exact same
default value behavior you described above:

function f(arg) {
  [a='a', b='b'] = arg;
  console.log(a+" "+b)}
let sparse = [,1];
f(sparse); // "a 1"
f([sparse[0],sparse[1]]); // "undefined 1"

>
> 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
>>
>
>



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

Reply via email to