Re: holes in spread elements/arguments

2011-10-08 Thread Brendan Eich
Hi Sean, I think you make a good case for hole preservation. However, holes in 
actual and formal parameter lists are not that wanted. You want them for 
consistency with holes in array pattern destructuring parameters. That's 
unusual, but I grant that if they're useful for destructuring, they could be 
useful for parameter lists too. In some languages, you would use a dummy name 
such as _.

The thing that gives me pause about extending the grammar for ArgumentList and 
FormalParameterList is the reports from Dean Landolt about comma first style 
users vs. comma last creating unintended holes in array literals. This is 
horrifying. It makes me abominate comma-first, but it also makes me want to be 
cautious about spreading holey syntax to parameter lists.

There are many kinds of consistencies to advance, along different dimensions. 
Some trade against others, directly or at an angle. Is this really worth the 
potential trouble?

/be

On Oct 5, 2011, at 12:19 PM, Sean Eagan wrote:

 On Mon, Oct 3, 2011 at 4:37 PM, Allen Wirfs-Brock al...@wirfs-brock.com 
 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'] = 

Re: holes in spread elements/arguments

2011-10-07 Thread David Herman
I don't think we can get away with repurposing _ as a pattern sigil, since it's 
already a valid identifier and used by popular libraries:

http://documentcloud.github.com/underscore/

In my strawman for pattern matching, I used * as the don't-care pattern:

http://wiki.ecmascript.org/doku.php?id=strawman:pattern_matching

Dave

On Oct 6, 2011, at 2:04 AM, Andreas Rossberg wrote:

 On 5 October 2011 21:19, Sean Eagan seaneag...@gmail.com wrote:
 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){}
 
 Only apropos of semantics, but I really don't like this syntax at all. It is 
 far, far too easy to overlook a hole. I think we should forbid this syntax in 
 Harmony.
  
 If we want to support holes in patterns -- and I'm all for it! -- then we 
 should do what all other languages with proper pattern matching do and 
 introduce explicit syntax for wildcards, namely _. That simplifies both 
 syntax and semantics (because it's more compositional) and increases 
 readability:
 
 function f([_, _, _, x]){}
 function f(_, _, _, x){}
 
 This has been suggested before, but I want to reinforce the point.
 
 (I'm far less convinced about allowing holes in expressions, but an argument 
 could be made that _ is simply syntax for undefined in expressions. No more 
 writing void 0.)
 
 /Andreas
 
 ___
 es-discuss mailing list
 es-discuss@mozilla.org
 https://mail.mozilla.org/listinfo/es-discuss

___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: holes in spread elements/arguments

2011-10-07 Thread Andreas Rossberg
On 7 October 2011 17:47, David Herman dher...@mozilla.com wrote:

 I don't think we can get away with repurposing _ as a pattern sigil, since
 it's already a valid identifier and used by popular libraries:

 http://documentcloud.github.com/underscore/

 In my strawman for pattern matching, I used * as the don't-care pattern:

 http://wiki.ecmascript.org/doku.php?id=strawman:pattern_matching


I reckoned that _ would be infeasible. But * is fine too, although it might
cause more headache in a fused pattern/expression grammar.

/Andreas
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: holes in spread elements/arguments

2011-10-05 Thread Sean Eagan
On Mon, Oct 3, 2011 at 4:37 PM, Allen Wirfs-Brock al...@wirfs-brock.com 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 

Re: holes in spread elements/arguments

2011-10-05 Thread Sean Eagan
Removing these inconsistencies would also allow argument and parameter
lists to be explained in terms of desugaring into array structuring
and destructuring patterns respectively:
function(a, , c = 0, ...d){  //...}
would desugar to:
function(){  var [a, , c = 0, ...d] = _arguments_; // even better
would be let!  //...}
and:
f(a, , c, ...d)
would desugar to:
Function.prototype.apply.call(f, undefined, [a, , c, ...d]);

On Wed, Oct 5, 2011 at 2:19 PM, Sean Eagan seaneag...@gmail.com wrote:
 On Mon, Oct 3, 2011 at 4:37 PM, Allen Wirfs-Brock al...@wirfs-brock.com 
 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 

Re: holes in spread elements/arguments

2011-10-04 Thread Sean Eagan
On Mon, Oct 3, 2011 at 5:11 PM, Allen Wirfs-Brock al...@wirfs-brock.com wrote:
 as it currently stands, a function is allowed to use both:

 function f(a,b,c,...rest) {
    g(...arguments);
    h(...rest);
 }

Rest parameters are capable of anything arguments objects are and
more, so what use case would there ever be for using both?  Your
example can be rewritten using only rest parameters as either:

function f(a,b,c,...rest) {
  g(...[a,b,c,...rest]);
  h(...rest);
}

or

function f(...arguments) {
  [,,,...rest] = arguments;
  g(...arguments);
  h(...rest);
}

Rest parameters are intended to deprecate `arguments`, if both are
allowed simultaneously then this deprecation will be much harder to
accomplish.  I would even go so far as to disallow the use of
`arguments` altogether in extended code, to encourage the use of
rest parameters and accelerate the deprecation of `arguments`.

 In a high perf implementation, the arguments to a function call will 
 typically be passed as a dense sequence of values on the processor stack.  
 Not as an actual array object. Such a sequence normally does not include any 
 way to encode the existence of holes so a new mechanism would have to be 
 added by implementors.  Probably a distinguished value.  Such mechanisms 
 typically carry a cost.  For example, such a distinguished internal marker 
 value must never be exposed to JS code as the value of formal parameter.  So, 
 the callee might have to scrub each argument position and replace each hole 
 with undefined.  It already has to do something like that for default value 
 parameters (based on the size of the argument list) but now it would have to 
 do it for every parameter.

Hopefully I'm not getting in way over my head here, but I did some
digging in spider monkey code, and here's what I found:
* There is already a distinguished value for array holes [1].
* The Function.prototype.apply code [1] loops over the passed argument
array [2], copying each element over to the argv structure of the
callee, explicity converting holes to undefined [3].  These
conversions could instead be done by the callee only for indexes
corresponding to non-rest formal parameters and indexes which may be
accessed from an arguments object, which as I argue above, should
never coexist with a rest parameter.  Indexes corresponding to a rest
parameter would not be coverted to holes, and thus hole preservation
would be acheived.
[1] 
http://dxr.mozilla.org/mozilla/mozilla-central/js/src/jsfun.cpp.html#l1866[2]
http://dxr.mozilla.org/mozilla/mozilla-central/js/src/jsfun.cpp.html#l1913[3]
http://dxr.mozilla.org/mozilla/mozilla-central/js/src/jsarray.cpp.html#l441[4]
http://dxr.mozilla.org/mozilla/mozilla-central/js/src/jsval.h.html#l259

Thanks,
Sean Eagan
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: holes in spread elements/arguments

2011-10-04 Thread Sean Eagan
On Tue, Oct 4, 2011 at 4:09 PM, Sean Eagan seaneag...@gmail.com wrote:
 On Mon, Oct 3, 2011 at 5:11 PM, Allen Wirfs-Brock al...@wirfs-brock.com 
 wrote:
 as it currently stands, a function is allowed to use both:

 function f(a,b,c,...rest) {
    g(...arguments);
    h(...rest);
 }

 Rest parameters are capable of anything arguments objects are and
 more, so what use case would there ever be for using both?  Your
 example can be rewritten using only rest parameters as either:

 function f(a,b,c,...rest) {
  g(...[a,b,c,...rest]);
   h(...rest);
 }

 or

 function f(...arguments) {
  [,,,...rest] = arguments;
  g(...arguments);
   h(...rest);
 }

 Rest parameters are intended to deprecate `arguments`, if both are
 allowed simultaneously then this deprecation will be much harder to
 accomplish.  I would even go so far as to disallow the use of
 `arguments` altogether in extended code, to encourage the use of
 rest parameters and accelerate the deprecation of `arguments`.

 In a high perf implementation, the arguments to a function call will 
 typically be passed as a dense sequence of values on the processor stack.  
 Not as an actual array object. Such a sequence normally does not include any 
 way to encode the existence of holes so a new mechanism would have to be 
 added by implementors.  Probably a distinguished value.  Such mechanisms 
 typically carry a cost.  For example, such a distinguished internal marker 
 value must never be exposed to JS code as the value of formal parameter.  
 So, the callee might have to scrub each argument position and replace each 
 hole with undefined.  It already has to do something like that for default 
 value parameters (based on the size of the argument list) but now it would 
 have to do it for every parameter.

 Hopefully I'm not getting in way over my head here, but I did some
 digging in spider monkey code, and here's what I found:
 * There is already a distinguished value for array holes [1].
 * The Function.prototype.apply code [1] loops over the passed argument
 array [2], copying each element over to the argv structure of the
 callee, explicity converting holes to undefined [3].  These
 conversions could instead be done by the callee only for indexes
 corresponding to non-rest formal parameters and indexes which may be
 accessed from an arguments object, which as I argue above, should
 never coexist with a rest parameter.  Indexes corresponding to a rest
 parameter would not be coverted to holes, and thus hole preservation
 would be acheived.
 [1] 
 http://dxr.mozilla.org/mozilla/mozilla-central/js/src/jsfun.cpp.html#l1866[2]
 http://dxr.mozilla.org/mozilla/mozilla-central/js/src/jsfun.cpp.html#l1913[3]
 http://dxr.mozilla.org/mozilla/mozilla-central/js/src/jsarray.cpp.html#l441[4]
 http://dxr.mozilla.org/mozilla/mozilla-central/js/src/jsval.h.html#l259

The sources got mangled, should be:

[1] http://dxr.mozilla.org/mozilla/mozilla-central/js/src/jsfun.cpp.html#l1866
[2] http://dxr.mozilla.org/mozilla/mozilla-central/js/src/jsfun.cpp.html#l1913
[3] http://dxr.mozilla.org/mozilla/mozilla-central/js/src/jsarray.cpp.html#l441
[4] http://dxr.mozilla.org/mozilla/mozilla-central/js/src/jsval.h.html#l259

Thanks,
Sean Eagan
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


argument lists as array structuring patterns and parameter lists as array destructuring patterns (Was Re: holes in spread elements/arguments)

2011-10-03 Thread Sean Eagan
So I guess my deeper question is why we can't just do the following:

* argument lists as array structuring patterns:

ArgumentList :
  ElementList

* parameter lists as array destructuring patterns:

ArrayBindingPattern :
  [ ArrayBindingElementList ]

FormalParameterList :
  ArrayBindingElementList

ArrayBindingElementList :
  Elisionopt BindingRestElementopt
  BindingElementList , Elisionopt BindingRestElementopt


ArgumentList and FormalParameterList could technically be replaced by
ElementList and ArrayBindingElementList respectively at this point,
just using them here for expository purposes.

The only difference I can see is that array structuring and
destructuring support elision whereas argument and parameter lists
currently do not.  But I'm not sure this difference makes sense, since
elision should be similarly useful at the function activation boundary
as it is at the assignment boundary.

Thanks,
Sean Eagan
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: holes in spread elements/arguments

2011-10-03 Thread Erik Arvidsson
But Function.prototype.apply doesn't preserve holes.
On Oct 3, 2011 6:50 AM, Sean Eagan seaneag...@gmail.com 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. 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 seaneag...@gmail.com wrote:
 On Thu, Sep 29, 2011 at 2:53 PM, Allen Wirfs-Brock
 al...@wirfs-brock.com 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
 es-discuss@mozilla.org
 https://mail.mozilla.org/listinfo/es-discuss
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: holes in spread elements/arguments

2011-10-03 Thread Sean Eagan
On Mon, Oct 3, 2011 at 10:30 AM, Erik Arvidsson
erik.arvids...@gmail.com wrote:
 But Function.prototype.apply doesn't preserve holes.

Function.prototype.apply doesn't preserve holes for the the
`arguments` object, but rest parameters aren't yet standardized, and
are intended to replace the `arguments` object, so they could, and in
my view, should preserve holes for both Function.prototype.apply and
foo(...args) activations, at least if array structuring and
destructuring preserve holes as currently specified in the ES.next
draft spec.

Thanks,
Sean Eagan
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: holes in spread elements/arguments

2011-10-03 Thread Allen Wirfs-Brock

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 seaneag...@gmail.com wrote:
 On Thu, Sep 29, 2011 at 2:53 PM, Allen Wirfs-Brock
 al...@wirfs-brock.com 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
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: holes in spread elements/arguments

2011-10-03 Thread Allen Wirfs-Brock

On Oct 3, 2011, at 8:45 AM, Sean Eagan wrote:

 On Mon, Oct 3, 2011 at 10:30 AM, Erik Arvidsson
 erik.arvids...@gmail.com wrote:
 But Function.prototype.apply doesn't preserve holes.
 
 Function.prototype.apply doesn't preserve holes for the the
 `arguments` object, but rest parameters aren't yet standardized, and
 are intended to replace the `arguments` object, so they could, and in
 my view, should preserve holes for both Function.prototype.apply and
 foo(...args) activations, at least if array structuring and
 destructuring preserve holes as currently specified in the ES.next
 draft spec.


In general, a call site doesn't have any knowledge of format of the formal 
parameter list of the callee and the callee doesn't have any knowledge of how 
the caller constructed the argument list. So the caller and callee argument 
semantics can't be interdependent. 

Also, we probably need to factor in the fact that most current implementations 
probably don't have a mechanism for passing holes in an argument and that 
adding such a mechanism might be a deep and expensive change.  Would the cost 
to implementors really be worth the benefit to JS developers?

Allen
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: holes in spread elements/arguments

2011-10-03 Thread Sean Eagan
On Mon, Oct 3, 2011 at 11:31 AM, Allen Wirfs-Brock
al...@wirfs-brock.com 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 seaneag...@gmail.com wrote:
 On Thu, Sep 29, 2011 at 2:53 PM, Allen Wirfs-Brock
 al...@wirfs-brock.com 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 

Re: holes in spread elements/arguments

2011-10-03 Thread Sean Eagan
On Mon, Oct 3, 2011 at 11:35 AM, Allen Wirfs-Brock
al...@wirfs-brock.com wrote:

 On Oct 3, 2011, at 8:45 AM, Sean Eagan wrote:

 On Mon, Oct 3, 2011 at 10:30 AM, Erik Arvidsson
 erik.arvids...@gmail.com wrote:
 But Function.prototype.apply doesn't preserve holes.

 Function.prototype.apply doesn't preserve holes for the the
 `arguments` object, but rest parameters aren't yet standardized, and
 are intended to replace the `arguments` object, so they could, and in
 my view, should preserve holes for both Function.prototype.apply and
 foo(...args) activations, at least if array structuring and
 destructuring preserve holes as currently specified in the ES.next
 draft spec.


 In general, a call site doesn't have any knowledge of format of the formal 
 parameter list of the callee and the callee doesn't have any knowledge of how 
 the caller constructed the argument list. So the caller and callee argument 
 semantics can't be interdependent.

I'm not suggesting the semantics of the caller and callee be
interdependent, just that the semantics of a function are dependent on
whether it has yet upgraded from `arguments` to rest parameters.

 Also, we probably need to factor in the fact that most current 
 implementations probably don't have a mechanism for passing holes in an 
 argument and that adding such a mechanism might be a deep and expensive 
 change.  Would the cost to implementors really be worth the benefit to JS 
 developers?

I have no implementation experience, but I don't see what cost you are
referring to.  It seems likely to me that there would be a performance
benefit since implementations don't need to add undefined values to
the rest parameter, and since user code can skip holes if desired such
as via ES5 Array extras.

Thanks,
Sean Eagan
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: holes in spread elements/arguments

2011-10-03 Thread Allen Wirfs-Brock

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

 On Mon, Oct 3, 2011 at 11:31 AM, Allen Wirfs-Brock
 al...@wirfs-brock.com 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 

Re: holes in spread elements/arguments

2011-10-03 Thread Allen Wirfs-Brock

On Oct 3, 2011, at 1:00 PM, Sean Eagan wrote:

 On Mon, Oct 3, 2011 at 11:35 AM, Allen Wirfs-Brock
 al...@wirfs-brock.com wrote:
 
 On Oct 3, 2011, at 8:45 AM, Sean Eagan wrote:
 
 On Mon, Oct 3, 2011 at 10:30 AM, Erik Arvidsson
 erik.arvids...@gmail.com wrote:
 But Function.prototype.apply doesn't preserve holes.
 
 Function.prototype.apply doesn't preserve holes for the the
 `arguments` object, but rest parameters aren't yet standardized, and
 are intended to replace the `arguments` object, so they could, and in
 my view, should preserve holes for both Function.prototype.apply and
 foo(...args) activations, at least if array structuring and
 destructuring preserve holes as currently specified in the ES.next
 draft spec.
 
 
 In general, a call site doesn't have any knowledge of format of the formal 
 parameter list of the callee and the callee doesn't have any knowledge of 
 how the caller constructed the argument list. So the caller and callee 
 argument semantics can't be interdependent.
 
 I'm not suggesting the semantics of the caller and callee be
 interdependent, just that the semantics of a function are dependent on
 whether it has yet upgraded from `arguments` to rest parameters.

as it currently stands, a function is allowed to use both:

function f(a,b,c,...rest) {
g(...arguments);
h(...rest);
}


 
 Also, we probably need to factor in the fact that most current 
 implementations probably don't have a mechanism for passing holes in an 
 argument and that adding such a mechanism might be a deep and expensive 
 change.  Would the cost to implementors really be worth the benefit to JS 
 developers?
 
 I have no implementation experience, but I don't see what cost you are
 referring to.  It seems likely to me that there would be a performance
 benefit since implementations don't need to add undefined values to
 the rest parameter, and since user code can skip holes if desired such
 as via ES5 Array extras.

In a high perf implementation, the arguments to a function call will typically 
be passed as a dense sequence of values on the processor stack.  Not as an 
actual array object. Such a sequence normally does not include any way to 
encode the existence of holes so a new mechanism would have to be added by 
implementors.  Probably a distinguished value.  Such mechanisms typically carry 
a cost.  For example, such a distinguished internal marker value must never be 
exposed to JS code as the value of formal parameter.  So, the callee might have 
to scrub each argument position and replace each hole with undefined.  It 
already has to do something like that for default value parameters (based on 
the size of the argument list) but now it would have to do it for every 
parameter.

Allen


___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: holes in spread elements/arguments

2011-09-30 Thread Sean Eagan
On Thu, Sep 29, 2011 at 2:53 PM, Allen Wirfs-Brock
al...@wirfs-brock.com 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
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: holes in spread elements/arguments

2011-09-30 Thread Erik Arvidsson
On Fri, Sep 30, 2011 at 15:27, Allen Wirfs-Brock al...@wirfs-brock.com wrote:

 On Sep 30, 2011, at 9:42 AM, Erik Arvidsson wrote:

 On Thu, Sep 29, 2011 at 12:53, Allen Wirfs-Brock al...@wirfs-brock.com 
 wrote:
 Also, note that I've currently spec'd ES6 so that 'arguments' can be used as
 a rest parameter name.  In other words
    function foo(...args) {return args}
 and
   function foo(...arguments) {return arguments}
 are semantically equivalent.
 I did this to  enable to make it easier to migrate code  such as:
    function foo() {baz(arguments)}
 to
    function foo(...arguments) {baz(arguments)}

 Minus the Arguments class I hope.


 I'm missing you point. What do you mean by Arguments class.
 as currently spec'd
   function foo(...arguments) {baz(arguments) }
 is semantically the same as
   function foo(...args) {baz(args) }

 The only difference is the name binding for the rest parameter.  In both 
 cases it is a regular Array object, not an ES5 arguments objects.

 Did you have something else in mind?

Nope. That covers it.

-- 
erik
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


holes in spread elements/arguments

2011-09-29 Thread Sean Eagan
Sorry to drag on about array holes, but:

Should holes in spread elements (e.g. [...holeyArray]) and arguments
(e.g. f(...holeyArray)) reflect as holes in the array they are spliced
into to avoid information loss ?  The current proposal [1] reflects
them as `undefined` values.

Spread arguments will reflect in both the `arguments` array and the
rest parameter binding if there is one, so this would allow them to
have holes.  The only issue I see is that Function.prototype.apply
reflects holes as `undefined` values in the `arguments` array, so if
`f` is a function whose code loops over `arguments` skipping holes
(most likely via ES5 Array extras), then the following migration could
cause holes to be skipped which were previously not:

f.apply(holeyArray)
-
f(...holeyArray)

This should be rare, since for one thing holey arrays are rare, and
it's unlikely anything important was being done with the `undefined`
values which are now being skipped.  If this is an issue, the holes
could only be reflected in rest parameter bindings since they are
meant to replace `arguments` in the long run anyways.

On a separate note, I'm not sure if argument lists should be made
symmetric to array element lists, by allowing them to have holes (e.g.
f(1, , 3)), but it would essentially allow `undefined` arguments to be
ommitted, if that would be considered useful.

[1] http://wiki.ecmascript.org/doku.php?id=harmony:spread

Thanks,
Sean Eagan
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: holes in spread elements/arguments

2011-09-29 Thread Allen Wirfs-Brock

On Sep 29, 2011, at 11:07 AM, Sean Eagan wrote:

 Sorry to drag on about array holes, but:
 
 Should holes in spread elements (e.g. [...holeyArray]) and arguments
 (e.g. f(...holeyArray)) reflect as holes in the array they are spliced
 into to avoid information loss ?  The current proposal [1] reflects
 them as `undefined` values.

You need to read the draft ES6 spec.  It specifies that spread used in array 
literals preserves holes.  I haven't written the spec. for spread in argument 
lists but clearly interior holes need to be passed as undefined.  Trailing 
holes in a spread in the final argument position could be trimmed but that 
would mean that:

foo.apply(undefined, new Array(5))
and
   foo(...(new Array(5))

wouldn't pass the same thing which seems like it would be an issue.


Allen
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: holes in spread elements/arguments

2011-09-29 Thread Sean Eagan
On Thu, Sep 29, 2011 at 1:31 PM, Allen Wirfs-Brock
al...@wirfs-brock.com wrote:

 On Sep 29, 2011, at 11:07 AM, Sean Eagan wrote:

 Sorry to drag on about array holes, but:

 Should holes in spread elements (e.g. [...holeyArray]) and arguments
 (e.g. f(...holeyArray)) reflect as holes in the array they are spliced
 into to avoid information loss ?  The current proposal [1] reflects
 them as `undefined` values.

 You need to read the draft ES6 spec.  It specifies that spread used in array 
 literals preserves holes.

Sorry.  I agree.

 I haven't written the spec. for spread in argument lists but clearly interior 
 holes need to be passed as undefined.  Trailing holes in a spread in the 
 final argument position could be trimmed but that would mean that:

So you don't think holes should appear in rest parameters or
`arguments` ?  The only reason I can think of to require that is that
old code may expect `arguments` not to contain holes, but then it
could be spec'ed that holes only appear in rest parameters.  Beyond
that is seems like it would make sense to be consistent with array
literal hole preservation.

Thanks,
Sean Eagan
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: holes in spread elements/arguments

2011-09-29 Thread Allen Wirfs-Brock

On Sep 29, 2011, at 12:14 PM, Sean Eagan wrote:

 On Thu, Sep 29, 2011 at 1:31 PM, Allen Wirfs-Brock
 al...@wirfs-brock.com wrote:
 
 ...
 
 I haven't written the spec. for spread in argument lists but clearly 
 interior holes need to be passed as undefined.  Trailing holes in a spread 
 in the final argument position could be trimmed but that would mean that:
 
 So you don't think holes should appear in rest parameters or
 `arguments` ?  The only reason I can think of to require that is that
 old code may expect `arguments` not to contain holes, but then it
 could be spec'ed that holes only appear in rest parameters.  Beyond
 that is seems like it would make sense to be consistent with array
 literal hole preservation.



No I don't. Currently there is no ways to syntactically generate an actual 
argument list with holes and I think that allowing ,, in argument lists is not 
particularly desirable. Also apply replaces holes with undefined so there is 
currently no way to create an arguments object that initially contains holes 
(somebody could delete elements after  it was created).  It seems highly 
desirable that we preserve the existing semantics of arguments 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]);
   }

regardless of how foo was called.  In other words,  baz(...bar) and 
baz.apply(undefined,bar) should always produce the same effect.

Also, note that I've currently spec'd ES6 so that 'arguments' can be used as a 
rest parameter name.  In other words
   function foo(...args) {return args}
and
  function foo(...arguments) {return arguments}
are semantically equivalent.

I did this to  enable to make it easier to migrate code  such as:
   function foo() {baz(arguments)}
to
   function foo(...arguments) {baz(arguments)}

allen


___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss