Re: What are the desired semantics of forEach for iterables?

On 22 Oct 2015, at 12:50 am, Boris Zbarsky <bzbarsky@mit.edu> wrote:
> 
> The current spec is at http://heycam.github.io/webidl/#es-forEach but clearly has some problems.
> 
> Specifically, we need to answer the following questions:
> 
> 1)  For two-type iterables, what should be passed as arguments to the callback function?  The obvious answer seems to be "value, key, this", with the index not passed at all.

I agree.  That matches Map.

> 2)  For one-type iterables, what should be passed as arguments to the callback function?  The two possible answers are "value, value, this" and "value, index, this"; the former matches Set and the latter matches Array.  The only one-type iterable I'm aware of shipping so far in browsers is DOMTokenList in Chrome, and this has the arraylike behavior, but it's also got an indexed getter so might be a special case anyway…

I’m not sure.

We might consider the fact that we have both iterable<> and setlike<>. If we have an object that behaves like a Set, then we should make it setlike<> rather than iterable<>. So if iterable<> is for more list-like things, I think it could make sense to invoke forEach like Array does.

On the other hand, does it make sense to invoke forEach with indexes if the interface won’t necessarily have a way to access items by index?

Also, having iterable<V> : setlike<V> :: iterable<K,V> : maplike<K,V> seems like a nice correspondence. 

> 3)  How should deletion and addition during iteration, especially deletion be handled?  The two possible answers are:
>  a) forEach starts an index at 0, increments it as it goes, uses that
>     to index into the list, stops when the index is greater than the
>     list length.  This means values can get skipped when an entry
>     that's already had forEach called on it is deleted.
>  b) forEach takes a list and ensures that all entries that were in it
>     before start and aren't deleted during the forEach callbacks, as
>     well as all entries added during forEach callbacks, get a callback.
> 
> Behavior (a) is what Array does.  Behavior (b) is what Set and Map do (though they handwave exactly how it's supposed to work).  Note that in both the Array and Map cases the behavior of forEach matches the behavior of iterating the object and calling the callback on each value the iterator returns.  In the case of IDL iterables, the iterator behavior is the Array-like behavior, with values possibly getting skipped.

No strong opinion except to say that for a one-type iterable, we should probably do (b) if we make forEach behave like Set’s forEach.

Received on Thursday, 29 October 2015 06:40:37 UTC