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

Reply via email to