- From: Allen Wirfs-Brock <allen@wirfs-brock.com>
- Date: Fri, 15 Nov 2013 09:28:52 -0800
- To: Jason Orendorff <jason.orendorff@gmail.com>, Boris Zbarsky <bzbarsky@mit.edu>
- Cc: public-script-coord@w3.org
- Message-Id: <754B8DBB-141D-4E96-A8EF-588C1838B8ED@wirfs-brock.com>
On Nov 15, 2013, at 8:24 AM, Jason Orendorff wrote: > On Fri, Nov 15, 2013 at 10:08 AM, Boris Zbarsky <bzbarsky@mit.edu> wrote: >> An obvious question that arises is what the definition of iterable is. >> >> Is it something for which HasProperty(obj, @@iterator) returns true? >> >> Is it something for which GetProperty(obj, @@iterator) returns something >> other than undefined? >> >> Is it something for which GetProperty(obj, @@iterator) returns a callable >> object? > > Array.from[1] has to make this determination, such that it can't "just > iterate and see". At the moment it is spec'd to use HasProperty(obj, > @@iterator). But that is inconsistent; other places where we check for > a method always use the third criterion. I hope Allen can weigh in. > > -j > > [1] http://people.mozilla.org/~jorendorff/es6-draft.html#sec-array.from > I already have an abstract operation GetIterator(obj) [1] to access an Iterator when an valid @@iterator must be present. If you trace through the steps (and unfortunately, the definition of Invoke is missing in this draft) you will see that the checks it performs are: Throws if any of the following are true, Type(obj) is not Object, obj[@@iterator] is undefined, obj[@@iterator] is not callable, Type(obj[@@iterator]()) is not Object. For consistency, I should probably define another abstract operation for use in the small number of places that conditionally check for an Iterable. Currently, Array.from [2] does a HasProperty(@@iterator) check followed by a call to GetIterator. In other words, the existence of an @@iterator property is all that is need to select the Iterator side of the union type. But that is then followed by validation specified via GetIterator. If the value of @@iterator doesn't validate you get a runtime exception rather than a fall back to the other side of the union type. There is one detail of the above that I think should change. Rather than doing HasProperty(@@iterator) to make the union type discrimination, it should do: 6 Let iteratorGetter = Get(items, @@iterator). 7.5 If iteratorGetter is undefined or null then let usingIterator be false; otherwise let usingIterator be true. (I'll actually do a bit more refactoring, but in the context of [2] those are the essential changes) This allows a subclass or individual object to disinherit support of an inherited @@iterator. So, going back to Boris's original question, you should discriminate an object as an Iteratable by this test: An object is an iterable if it has a @@iterator whose value is neither undefined or null. An object that has an @@interator property whose value (other than undefined or null) is not a function is still consider to be an Iterable, but it is malformed. Actually trying to retrieve its Iterator will produce a runtime error. [1]: http://people.mozilla.org/~jorendorff/es6-draft.html#sec-getiterator [2]: http://people.mozilla.org/~jorendorff/es6-draft.html#sec-array.from steps 6-8
Received on Friday, 15 November 2013 17:29:27 UTC