I don't understand why we need IterableOnce ? Was: Proposal: JDK-8148917 Enhanced-For Statement Should Allow Streams

forax at univ-mlv.fr forax at univ-mlv.fr
Fri Mar 15 08:03:38 UTC 2019


----- Mail original -----
> De: "Peter Levart" <peter.levart at gmail.com>
> À: "Remi Forax" <forax at univ-mlv.fr>
> Cc: "Brian Goetz" <brian.goetz at oracle.com>, "Stuart Marks" <stuart.marks at oracle.com>, "core-libs-dev"
> <core-libs-dev at openjdk.java.net>
> Envoyé: Vendredi 15 Mars 2019 08:57:10
> Objet: Re: I don't understand why we need IterableOnce ? Was: Proposal: JDK-8148917 Enhanced-For Statement Should Allow
> Streams

> Hi,
> 
> On 3/14/19 9:51 PM, Remi Forax wrote:
>> yes, i think i prefer this solution, one Iterable to rule them all.
>>
>> First, it's not in the spirit of the Collection API to multiply the interfaces,
>> by example, we have only one kind of Iterator and not an Iterator and a
>> ReadOnlyIterator even if a lot of iterators doesn't implement remove. It's a
>> central design of the Collection API, reduce the number of interfaces to ease
>> the use even if it means that each interface may have a broader definition. The
>> Collection API design has chosen his side between users and library writers
>> (people that provides implementations) because from the library writer point of
>> view you can not specify exactly the semantics you want.
>>
>> Then from the user POV, what is point of IterableOnce ? I will not using it as
>> parameter because using Iterable is a super-type (like i will use a List
>> instead of an ArrayList as parameter) and if i using it as return type, codes
>> that call that method can put it in an Iterable, this is exactly what the
>> for-each-loop will do BTW, so it's seems useless.
>>
>> Also as Peter said, there are already codes in the wild that create an Iterable
>> that can only be iterated once, ASM has such class, if IterableOnce is added to
>> the JDK, i will have people ask me to retrofit the ASM class to use
>> IterableOnce just for the sake of having the right semantics ? So basically by
>> introducing IterableOnce, all codes that were perfectly fine in term of
>> semantics before introducing IterableOnce are now not quite right because they
>> are not implementing the right interface ? Hum, i think i still not get why we
>> need such interface.
>>
>> Rémi
> 
> The IterableOnce really does not have utility as a static type and I
> think it might only confuse some (Should I return IterableOnce here?
> Should I consume IterableOnce here? Many would not get the difference at
> first). So in this respect it would be better that there is no
> IterableOnce. But there is a runtime utility (although a marginal one)
> where the code can take two branches depending on iterable implementing
> IterableOnce or not. Similar to RandomAccess marker interface with
> List(s). So the question is whether this situation would be better
> served by introducing an unrelated marker interface instead of a subtype
> of Iterable? For example:
> 
> 
> /**
>  * Implementing this interface allows an object to be the target of the
> enhanced
>  * {@code for} statement (sometimes called the "for-each loop" statement).
>  * <p>
>  * There are generally two kinds of {@code Iterable} implementations:
>  * <ul>
>  * <li>Those that allow
>  * multiple calls to {@link #iterator()} each returning new instance
> which can
>  * be used for independent iterations over elements. {@link
> java.util.Collection}s
>  * are general representatives of this type of {@code Iterable}s.
>  * </li>
>  * <li>And those that allow only one call to {@link #iterator()},
> providing a
>  * single iteration and throwing {@link IllegalStateException} on 2nd
> and subsequent
>  * calls. It is recommended that this kind of implementations also
> implement
>  * {@link Once} marker interface to allow code to detect the kind of
> {@code Iterable}
>  * during runtime. {@link java.util.stream.Stream} is an example
> implementation
>  * of this type of {@code Iterable}.
>  * </li>
>  * </ul>
>  *
>  * @param <T> the type of elements returned by the iterator
>  * @jls 14.14.2 The enhanced {@code for} statement
>  * @since 1.5
>  */
> public interface Iterable<T> {
> 
>     /**
>      * Marker interface used by {@code Iterable} implementations to
> indicate that
>      * they support only a single call to {@link #iterator()} method
> while 2nd and
>      * subsequent calls throw {@link IllegalStateException}. The primary
>      * purpose of this interface is to allow generic algorithms to
> alter their
>      * behavior if they need multiple passes over elements of {@link
> Iterable}.
>      *
>      * @since 13
>      */
>     interface Once {}
> 
> 
> What do you think of that?

It's not clear to me if an annotation, available at runtime, is not a better fit.
Anyway, i'm not sure not sure introducing such interface/annotation worth its maintenance cost, as you said the use case is pretty narrow.

> 
> Regards, Peter

Rémi


More information about the core-libs-dev mailing list