On Oct 3, 2011, at 12:42 PM, Sean Eagan wrote:

> 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:
>> 
>>> ...
> 
>> 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));

Look at the specification of apply in section 15.3.4.3 of the ES5/5.1 spec.  It 
does a [[Get]] on each element of the argArray to get the value that passed in 
the argument list.  [[Get]] converts holes to undefined.

> 
> syntactic calls will support holes...
> 
> f(...Array(5))

by syntactic calls I meant f(a,b,c).  the legacy language does not allow for 
f(a,,c)
> 
> 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.

Sorry that is incorrect, see 15.3.4.3

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

Because we aren't talking about reification of arguments.  We are talking about 
the semantics of an argument list in a function call expression and the 
semantics of the spread operator.

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

Apply is on the caller side.  It doesn't have any parameter semantics at all.  
It is only responsible for passing on a valid argument list.

Because apply and normal function application can't depend knowledge to the 
callee, it is reasonable to expect that:
   foo.apply(undefined,x)
means exactly the same thing as
   foo(...x)


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

then what would be the value of x in function(x=1) {}(...[])  ??

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

The above line is not legal syntax according to the current specification 
draft.  The destructuring binding pattern and a destructuring assignment 
pattern have both different syntax and semantics.

In a destructuring binding, a scalar BindingElement is defined as:
   SingleNameBinding : BindingIdentifier Initializer-opt
while in a destructuring assignment, a scalar AssignmentElement is defined as
   AssignmentElement : LeftHandSideExpression

Note that an AssignmentElement does not have an Initializer.  The reason I 
defined it this way is that unlike a BindingIdentifier, a 
LeftHandSideExpression can be an arbitrary complex expression. I didn't want to 
allow expressions such as:
   [new foo.bar[baz(x=5)].bam=0] = obj;
where the trailing initializer looks like it is just part of the element 
expression.  I'm willing to discuss the merits of that decision, but the fact 
remains that the semantics of destructuring binding and destructuring 
assignment are quite different so I consider suspect any argument that starts 
by assuming that they are the same.

Allen

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

Reply via email to