I don't understand why we need IterableOnce ? Was: Proposal: JDK-8148917 Enhanced-For Statement Should Allow Streams
Peter Levart
peter.levart at gmail.com
Fri Mar 15 07:57:10 UTC 2019
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?
Regards, Peter
More information about the core-libs-dev
mailing list