15.3.4.3 Function.prototype.apply (thisArg, argArray)

classic Classic list List threaded Threaded
8 messages Options
Reply | Threaded
Open this post in threaded view
|

15.3.4.3 Function.prototype.apply (thisArg, argArray)

Asen Bozhilov
ES5 does some changes in Function.prototype.apply. It allows generic
array-like object for a second argument of `apply' method.

| 6. Let n be ToUint32(len).
| 7. If n is not equal to ToNumber(len), then throw a TypeError exception.

Isn't better to throws a RangeError instead of TypeError? Is this a
typo or it must be a observable behavior of `apply'?
_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss
Reply | Threaded
Open this post in threaded view
|

Re: 15.3.4.3 Function.prototype.apply (thisArg, argArray)

Jeff Walden-6
Check out the ES5 erratum -- steps 5 and 7 have been removed.

http://wiki.ecmascript.org/doku.php

Jeff
_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss
Reply | Threaded
Open this post in threaded view
|

Re: 15.3.4.3 Function.prototype.apply (thisArg, argArray)

Asen Bozhilov
Jeff Walden:
> Check out the ES5 erratum -- steps 5 and 7 have been removed.
>
> http://wiki.ecmascript.org/doku.php

Thank you for the link, but I have some question about this. Now I can
pass array like object with strange length property and this is not
cause an Error. For example:

length = -1;

After ToUint32(length) it is equal to: 4294967295
Does it make sense that? Now I can use and length value which is
higher that pow(2, 32) - 1.
I think RangeError is better here. As I understand generic array like
object. It is an object which can safe converted to array object. It
will be good if ECMA-262 specified what is an array like object.
_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss
Reply | Threaded
Open this post in threaded view
|

Re: 15.3.4.3 Function.prototype.apply (thisArg, argArray)

Jose Antonio Perez-2
The aim has been consistency. All Array generic own methods that explicitly use the length property have the same behavior:

- Let lenVal be the result of calling the [[Get]] internal method of O with argument "length".
- Let len be ToUint32(lenVal).

Function.prototype.apply  now  behave the same way.

You've been quite right in your proposal  ..
 
I think RangeError is better here.


... but if you change the behavior of Function.prototype.apply , it would be necessary also modify the behavior of the Array.prototype methods for consistency.

 
As I understand generic array like
object. It is an object which can safe converted to array object. It
will be good if ECMA-262 specified what is an array like object.

Strongly agree!

Jose

_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss
Reply | Threaded
Open this post in threaded view
|

Re: 15.3.4.3 Function.prototype.apply (thisArg, argArray)

Jose Antonio Perez-2
In ES5-15.4 is clearly defined what is an index and  what conditions must verify length

"A property name P (in the form of a String value) is an array index if and only if ToString(ToUint32(P)) is equal to P and ToUint32(P) is not equal to 2^32−1"

"Every Array object has a length property whose value is always a nonnegative integer less than 2^32"

Also in the construction of an array  with explicit length (15.4.2.2) that condition is checked with a possible RangeError exception

"If the argument len is a Number and ToUint32(len) is equal to len, then the length property of the newly constructed object is set to ToUint32(len). If the argument len is a Number and ToUint32(len) is not equal to len, a RangeError exception is thrown."

As Asen suggests would be interesting to define explicity the concept of "Array like object",  demanding the fulfillment of such conditions.

Jose


_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss
Reply | Threaded
Open this post in threaded view
|

RE: 15.3.4.3 Function.prototype.apply (thisArg, argArray)

Allen Wirfs-Brock-2

If we assume “Array like object” is an object that can serve as the this value of the Array.prototype methods then pretty much any object  is “Array like”.  The Array.prototype methods generally iterate based upon the value of the this object’s length property. They use ToUint32  to interpret length as a positive value in the 0..2^32-1 range.  If the this object does not have a length property, [[Get]] will return undefined which ToUint32 converts to 0.  All other non-numeric values  also convert to values in the 0..2^32-1 range.  Things like non-numeric string values first convert to NaN and then to 0.

 

So objects without a length or with a length value for which ToNumber produces NaN are treated as 0 length “arrays”.

 

If the converted length is non-zero, then the algorithms iterate over the “array indexed” property names between 0 and ToUint32(length)-1.  Each property is accessed individually and may or may not actually exist.  Specific behavior for each “array indexed” property (whether present or not) is defined by each algorithm.

 

Hence, all objects are “array like”.  Some are just more obviously (or usefully)) so than others.

 

Regarding, passing an object whose length is -1 to apply as the “array” of arguments.  As has been pointed out, -1 would be interpreted as +2^32-1 – a very large array.  It is reasonable to assume that all implementations have some limit (perhaps dynamically determined) on the size of an argument list that can be passed to a function so such an object would presumably trip that limit.  The actual limit value and the action that occurs is not specified by ES5.

 

Some will make an argument that all such limits should be made explicit in the specification.  However, that is probably folly.  There are dozens of places in the specification where plausible implementation limits might be encountered.  In many cases, the specific would have to pick an arbitrary limit value as there is no obvious natural limit value.  Even if a such values were specified, there is little reason to believe that implementation would actually respect them.  Often actual limits are determined dynamically based upon various available resources.  What’s an implementation going to do if the spec. says it must support arguments list of up to 1000 elements but that exhausts  available stack space for some specific call.  It’s still going to fail, regardless of what the spec. says.

 

While trying to spec. all possible implementation limits is probably not a very good idea.  It may make sense to specify what should happen if an implementation limit is exceeded.  Probably throwing some specific exception. 

 

Allen

From: [hidden email] [mailto:[hidden email]] On Behalf Of Jose Antonio Perez
Sent: Thursday, October 28, 2010 8:41 AM
To: Asen Bozhilov
Cc: es-discuss
Subject: Re: 15.3.4.3 Function.prototype.apply (thisArg, argArray)

 

In ES5-15.4 is clearly defined what is an index and  what conditions must verify length

 

"A property name P (in the form of a String value) is an array index if and only if ToString(ToUint32(P)) is equal to P and ToUint32(P) is not equal to 2^32−1"

 

"Every Array object has a length property whose value is always a nonnegative integer less than 2^32"

 

Also in the construction of an array  with explicit length (15.4.2.2) that condition is checked with a possible RangeError exception

 

"If the argument len is a Number and ToUint32(len) is equal to len, then the length property of the newly constructed object is set to ToUint32(len). If the argument len is a Number and ToUint32(len) is not equal to len, a RangeError exception is thrown."

 

As Asen suggests would be interesting to define explicity the concept of "Array like object",  demanding the fulfillment of such conditions.

 

Jose

 


_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss
Reply | Threaded
Open this post in threaded view
|

Re: 15.3.4.3 Function.prototype.apply (thisArg, argArray)

Jose Antonio Perez-2

If we assume “Array like object” is an object that can serve as the this value of the Array.prototype methods then pretty much any object  is “Array like”.  The Array.prototype methods generally iterate based upon the value of the this object’s length property. They use ToUint32  to interpret length as a positive value in the 0..2^32-1 range.  If the this object does not have a length property, [[Get]] will return undefined which ToUint32 converts to 0.  All other non-numeric values  also convert to values in the 0..2^32-1 range.  

 

So objects without a length or with a length value for which ToNumber produces NaN are treated as 0 length “arrays”.

 


Actually we are discussing two possible positions:
- Any object is an Array-like-object
- An Array-like-object  is an object that has a integer length property that in interval [0,2^32) 



_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss
Reply | Threaded
Open this post in threaded view
|

Re: 15.3.4.3 Function.prototype.apply (thisArg, argArray)

Garrett Smith
In reply to this post by Allen Wirfs-Brock-2
On 10/28/10, Allen Wirfs-Brock <[hidden email]> wrote:
> If we assume “Array like object” is an object that can serve as the this
> value of the Array.prototype methods then pretty much any object  is “Array
> like”.  The Array.prototype methods generally iterate based upon the value
> of the this object’s length property. They use ToUint32  to interpret length
> as a positive value in the 0..2^32-1 range.  If the this object does not
> have a length property, [[Get]] will return undefined which ToUint32
> converts to 0.  All other non-numeric values  also convert to values in the
> 0..2^32-1 range.
...xxx

0..2^32-2.

Remember, length is at most 2^32-1. The largest array index must
necessarily be 1 less than that.

http://ecma262-5.com/ELS5_HTML.htm#Section_15.4

Things like non-numeric string values first convert to NaN
> and then to 0.
>
> So objects without a length or with a length value for which ToNumber
> produces NaN are treated as 0 length “arrays”.
>

This seems to be a different argument: That any object can be used in
an array method.

Array-like has come up before here, once proposed by me, later, by Mike Samuel.

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