On Mon, Oct 3, 2011 at 4:37 PM, Allen Wirfs-Brock <[email protected]> wrote:
> 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.
The only way this is observable in ES5 is if argArray has getters for
any of the indexes between 0 and argArray.length. I'm not aware of
any cases of objects defining getters for indexed properties, much
less those objects being passed to Function.prototype.apply. So the
only consequence of this is that the hole preservation algorithms in
the draft spec only call [[Get]] when [[HasProperty]] returns true.
So we could either tweak the hole preservation algorithm for rest
parameters to call [[Get]] regardless, or the better option IMHO,
match the other algorithms by no longer calling [[Get]] for holes in
argArray, at least when Function.prototype.apply is called from
extended code.
>
> 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)
This can be said of any any syntax being added in ES.next. Also, I'm
only suggesting to add that syntax if it continues to be available in
array literals.
> 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
You are correct, sorry. However, this is merely an unobservable
specification detail, so what relevance does it have to what is best
for the future of the language ?
> 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.
The spread operator in argument lists reifies the argument list as an
array in my view. But mostly I just care that the semantics are the
same as when the spread oeprator occurs in an array literal, i.e. that
holes are preserved for the receiver. If a caller does not want holes
to be observed by a potential callee rest argument, they can use a
dense argument list, however I'm not sure why they would care about
this. If a caller *does* want to allow a potential callee rest
parameter to utilize holes for optimization purposes, why prevent them
from doing so?
> 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)
>
Yes, I intend for them to mean the same thing, which is that holes in
x which fall within a range covered by a rest parameter in foo are
preserved. If foo uses `arguments` they continue to show up as
undefined values there.
> 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.
Sorry, should have read the draft spec more thoroughly, I agree that
assignment destructuring should have syntactic and semantic
differences from binding destructuring.
However, I don't see why variable declaration array destructuring
binding and parameter lists should be different in any way. The only
current syntactic difference between them is elision:
// allowed
function f([,,,,,,x]){}
// disallowed
function f(,,,,,,x){}
The same syntactic inconsistency exists between array structuring and
argument lists:
// allowed
f([,,,,,,x]);
// disallowed
f(,,,,,,x);
The only semantic inconsistencies are:
* hole preservation (if function rest parameters do not, but array
destructuring rest parameters do, as you suggest)
* default value triggering:
// default not used
(function(x = 0){})(...[,1])
// default used
var [x = 0] = [,1];
To me, eliminating these inconsistencies is a clear win, since it
eliminates separate syntax and semantics for FormalParameterList and
ArgumentList in the spec, implementations, and user's minds. I would
prefer to have elision, hole preservation, and defaulting based on
input array length rather than holes, but only if they were
consistently applied.
Thanks,
Sean Eagan
_______________________________________________
es-discuss mailing list
[email protected]
https://mail.mozilla.org/listinfo/es-discuss