Andy Wingo (2014-03-03T09:46:36.000Z)
On Mon 03 Mar 2014 10:35, David Bruant <bruant.d at gmail.com> writes:

> Le 03/03/2014 10:11, Andy Wingo a écrit :
>> On Sun 02 Mar 2014 04:18, Domenic Denicola <domenic at domenicdenicola.com> writes:
>>
>>> You can just do `if (Symbol.iterator in potentialIterable)`.
>> Of course, this can introduce time-of-check-to-time-of-use bugs.
>> Actually calling @@iterator on the iterable is more reliable.
> This only shifts the problem one step without really solving it.

An iterable is simply an object with a callable @@iterator property.
Calling @@iterator on an object and getting back a result is the
sum-total of the iterator structural type -- so yes, this problem is
solved.

> Calling @@iterator may return a non-iterator or may return something
> that looks like a iterator ('next' method), but throws when calling
> 'next'.

This is why the for-of and yield* desugarings eagerly get the "next"
property on the iterator, and then use that property as a method all the
way through.  (And of course it can throw.)

> I wonder if time-of-check-to-time-of-use bugs can be fully avoided
> entirely in JS?

To an extent, but it's hard; see Object.freeze et al.  Anyway that's
beside the point.  The spec tries to eliminate all the bugs that it can,
and the case of "get me an iterator from an iterable" or "prepare to
call 'next' on this presumed iterable" are cases in which it can help.

Andy
domenic at domenicdenicola.com (2014-03-06T23:05:29.217Z)
On Mon 03 Mar 2014 10:35, David Bruant <bruant.d at gmail.com> writes:

> This only shifts the problem one step without really solving it.

An iterable is simply an object with a callable @@iterator property.
Calling @@iterator on an object and getting back a result is the
sum-total of the iterator structural type -- so yes, this problem is
solved.

> Calling @@iterator may return a non-iterator or may return something
> that looks like a iterator ('next' method), but throws when calling
> 'next'.

This is why the for-of and yield* desugarings eagerly get the "next"
property on the iterator, and then use that property as a method all the
way through.  (And of course it can throw.)

> I wonder if time-of-check-to-time-of-use bugs can be fully avoided
> entirely in JS?

To an extent, but it's hard; see Object.freeze et al.  Anyway that's
beside the point.  The spec tries to eliminate all the bugs that it can,
and the case of "get me an iterator from an iterable" or "prepare to
call 'next' on this presumed iterable" are cases in which it can help.