Why does Array.from accept non-iterable arraylikes?

Brandon Benvie bbenvie at mozilla.com
Tue Jun 25 19:36:09 PDT 2013

On 6/25/2013 2:17 PM, Jason Orendorff wrote:
> On Tue, Jun 25, 2013 at 3:19 PM, Brandon Benvie <bbenvie at mozilla.com> wrote:
>> It's not just about backward compatibility, but also usability. Mandating
>> the addition of a non-symbol property in order to work with a protocol (in
>> this case the iterator protocol) is not good.
> I don't buy this. Dynamic languages are full of protocols -- any time
> a function calls a method on an argument, there's a protocol involved.
> Duck typing.
> Now that JS is getting symbols, things might change, but I expect
> methods will still have plain old string names, just like always. The
> class syntax was designed with this assumption.
>>      var dict = Object.create(null);
>>      Object.defineProperty(dict, 'iterator', { value: function*(){ /*...*/ }
>> })
> You can certainly still use an object as a worse-is-better dictionary;
> you'd just leave the iterator code outside of the object:
>      function* props(obj) {
>          for (var k in obj)
>              yield [k, obj[k]];
>      }
>      for (let [k, v] of props(dict))
>          ...
> This is probably what you'd want to do anyway. It's less code.
> Since you want something iterable, it's also worth considering Map.
> Iteration built in!
>> It's `__proto__` all over again (looking at __proto__ as the "get/set [[Prototype]] protocol"). Just say no.
> ...Oh, that seems like a bit much. __proto__ was opt-out, for one
> thing. Iterators are opt-in.
> -j

I agree that Map is better than dict, __proto__ is opt in, etc. Using 
"iterator" smelled wrong to me and I hadn't fully thought through 
exactly why. I should have made the point more directly.

Symbols provide a way of exposing meta-object protocol extension points 
via the normal object protocol without requiring a cumbersome layer of 
stratification, such as how Proxies separate the handler from the 
exposed object (the proxy). Things that tie into syntax or spec 
internals are prime targets for exposure through this way, such as 
@@create and @@hasInstance (as well as proposed ideas such as @@call, 
@@construct, @@geti, @@seti, etc.).

I think that the iteration protocol falls under the type of thing that 
is better exposed through this layer of faux-stratification rather than 
completely unstratified, due to its primary use in supporting syntax 
(for-of). The reason there's any argument against it is because, unlike 
most of the other extension points, there's some amount of "manually 
cranking the wheel" that can be useful with the iteration protocol.

(I also don't think that polyfillability is a good argument here, 
because as I said before, it's possible to create a polyfill that works 
in ES3-ES6 that provides a compatibility layer over iteration.)

More information about the es-discuss mailing list