----- Mail original ----- > De: "Peter Levart" <peter.lev...@gmail.com> > À: "Remi Forax" <fo...@univ-mlv.fr> > Cc: "Brian Goetz" <brian.go...@oracle.com>, "Stuart Marks" > <stuart.ma...@oracle.com>, "core-libs-dev" > <core-libs-dev@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