array like objects

On Sat, Dec 12, 2009 at 4:04 PM, Mark S. Miller <erights at google.com> wrote:
> On Sat, Dec 12, 2009 at 3:38 PM, Garrett Smith <dhtmlkitchen at gmail.com>
> wrote:
>>>> On Sat, Dec 12, 2009 at 2:59 PM, Mark S. Miller <erights at google.com>
>> wrote:
>> > Are we really this stuck? Can anyone think of a reliable, portable, and
>> > fast
>> > ES3R test that tests whether a property is enumerable, whether it is
>> > inherited or not?
>> >
>>>> Not stuck. Why do you care if |length| is enumerable?
>>>> If a standard |for| loop is used, it doesn't matter. Why anyone would
>> want to use |for in| for something that is arrayLike?
>>> |for in| is not my concern. I wish a predicate that has little chance of
> false positives against legacy ES3 user constructed objects.
Why the need to distinguish between a user-defined object that is
intended for iteration vs one that is not? The program should already
know. If the needs of a program are to iterate over an object's
indexed properties, possibly filtering, mapping, etc, then allowing
the algorithm to throw errors at Step 0 seems like a recipe for IE (a
disaster).
[snip]
I am still a bit fuzzy on what your "arrayLike" means or is intended
for. Allen pointed out on previous thread[1] that Array generic
methods provide an implicit contract. What that contract is depends on
the method and arguments.
Array.prototype.slice, when supplied with one argument, has the
following implicit contract for the thisArg:
1) [[Get]]
2) [[HasProperty]] checks
An object that can do those two, but also has a - length - property
has enough functionality so that a call to - ([]).slice.call( anObject
) - would be expected to return an array that has anObject's numeric
properties, except for the specification allowing "anything goes" with
Host object and we see "JScript Object Expected" errors in IE.
Allen has not yet commented on that.
Stronger wording for Host object in ES specification would provide
stronger incentive for implementations (IE) to use host objects that
have consistent functionality. IOW, if the Array.prototype.slice says:
| 2. Call the [[Get]] method of this object with argument "length".
[[Get]] works via property accessor operators, as in:-
k = anObject.length >>> 0;
- then that step of the algorithm should succeed.
Once an Array is obtained, then the program can use the other
Array.prototype methods on that object. Alternatively, if the
object's functionality is known by the programmer and the
functionality fulfills an implicit contract for a generic method, then
the program should be able to use that method, host object or not. At
least, I would like it to be that way.
| var anObject = document.body.childNodes;
| function fn( obj ) { return /foo/.test(obj.className); };
| Array.prototype.filter.call( anObject, fn );
Or (Spidermonkey only):
| function fn( obj ) { return /foo/.test(obj.className); }
| Array.filter( document.body.childNodes, fn );
ES5 allows the algorithm to terminate at step 0, so that approach is
not viable.
A for loop could be used, however the downside to that now the program
uses a user-defined makeArray function.
makeArray( anObject ).
filter( function(obj) { return /foo/.test(obj.className); });
Which requires double iteration over the collection, plus the overhead
of an extra call, plus the extra makeArray function, downloaded and
interpreted and loaded in memory. This sort of thing is often mired in
the bowels of today's popular libraries.
In contrast, the generic algorithm in question could be specified to
execute each step, regardless of whether or not the argument is a host
object.
Whether or not the execution of that step results in error depends on
the particular object's implementation. This way, if an object
supports [[Get]], an Array method that calls [[Get]] could be expected
to succeed. However if the object has a readonly - length - property,
or - length - is a getter with no setter, then it would be expected to
throw an error.
Is this idea reasonable or feasable, from a spec standpoint or
implementation standpoint?
This is a very very old issue these errors are still coming in IE8,
but do not appear in other major browsers (AFAIK). Is stronger wording
for host objects a good idea?
Garrett
[1]https://mail.mozilla.org/pipermail/es-discuss/2009-May/009310.html
[2]https://mail.mozilla.org/pipermail/es-discuss/2009-December/010241.html