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