Array extras feedback
On Fri, 31 Jul 2009 01:55:53 +0200, Jeff Walden <jwalden+es at mit.edu> wrote:
Brendan asked me yesterday to look at and comment on the array extras
methods as they exist in ES5, since things are being finalized yesterday
and today. (I'm not sure whether yesterday was the latest to make these
comments or whether today is also acceptable; unfortunately Black Hat
proceedings destroyed my day yesterday. So it goes.) Overall they look
fine; I find myself somewhat amused that the descriptions in the spec
are apparently copied from MDC with slight modifications, improvements,
and clarifications. :-)
Rereading them, I also notice this wording in the "reduce" function:
"callbackfn should be a function that takes four arguments. reduce calls
the callback, as a
function, once for each element present in the array, in ascending order."
If the optional initalValue is omitted, reduce actually does one less call
(omitting the call
for the first element).
The "ascending order" doesn't specify that it's the order of the element's
indices,
not their value.
There is a similar problem in the reduceRight function.
javascript:[].indexOf(2,{valueOf: function() {alert("valueof"); return -1}})
My quick experiments show that Firefox (3.5.1) does the early exit as currently spec'ed by ES5 while Chrome (2.0.172.37), Safari (4.0), and Opera ( 9.63) exhibit the side-effect before returning. Note that the actual FF behavior is different from Mozilla's published algorithm which is apparently what the other browsers implemented.
I'm not aware of any articulated pattern for JavaScript functions regarding whether or not arguments should be fully evaluated for side-effects. As there is a divergence among implementations and since we are trying to close down changes to the draft I'm inclined to leave things as currently specified unless some there are strong arguments to support making the change.
On 31.7.09 08:47, Allen Wirfs-Brock wrote:
javascript:[].indexOf(2,{valueOf: function() {alert("valueof"); return -1}})
My quick experiments show that Firefox (3.5.1) does the early exit as currently spec'ed by ES5 while Chrome (2.0.172.37), Safari (4.0), and Opera ( 9.63) exhibit the side-effect before returning. Note that the actual FF behavior is different from Mozilla's published algorithm which is apparently what the other browsers implemented.
I'm not aware of any articulated pattern for JavaScript functions regarding whether or not arguments should be fully evaluated for side-effects. As there is a divergence among implementations and since we are trying to close down changes to the draft I'm inclined to leave things as currently specified unless some there are strong arguments to support making the change.
Oh, hm, you're right; I missed that when transcribing the C implementation to JS, and I was looking at the JS implementations as a shortcut to avoid having to get bogged down in verbose C++. I guess that lessens the concern; I'm not sure it eliminates it, still seems like a somewhat odd inconsistency.
Brendan asked me yesterday to look at and comment on the array extras methods as they exist in ES5, since things are being finalized yesterday and today. (I'm not sure whether yesterday was the latest to make these comments or whether today is also acceptable; unfortunately Black Hat proceedings destroyed my day yesterday. So it goes.) Overall they look fine; I find myself somewhat amused that the descriptions in the spec are apparently copied from MDC with slight modifications, improvements, and clarifications. :-)
The biggest change, using SameValue rather than ===, is certainly a good change; we should have noticed that when creating the method in the first place.
The only real issue I noticed -- a small issue, not especially critical but worth noting in passing, was this: indexOf and lastIndexOf return early if this array-like object has length zero. In particular they return before this step (the only side-effectful step that's short-circuited):
If argument fromIndex was passed let n be ToInteger(fromIndex); else let n be len.
Thus, when indexOf and lastIndexOf are used, the provided fromIndex is converted to an integer -- except when this array is empty. Why should this behavior differ when the array has one element and when it has zero? I believe it would be more consistent for fromIndex to always be converted to integer (assuming the callback is properly callable and that the indexOf call otherwise conforms to expected use), even if this array is empty.
Anyway, if this doesn't make it in time to be considered, so be it. If it does, I'm not arguing particularly vociferously in favor of it, but it seems like an unnecessary difference from what we've already implemented, and I don't see an obvious motivation for it.