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

Remi Forax forax at univ-mlv.fr
Thu Mar 14 20:51:02 UTC 2019

----- Mail original -----
> De: "Peter Levart" <peter.levart at gmail.com>
> À: "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é: Mardi 12 Mars 2019 18:34:58
> Objet: Re: Proposal: JDK-8148917 Enhanced-For Statement Should Allow Streams

> On 3/12/19 5:04 PM, Brian Goetz wrote:
>> No. You have the LSP backwards (though this is easy to do.)
>> IterableOnce means "*must throw* on subsequent use"; under this spec,
>> an arbitrary Iterable is most certainly *not* an IterableOnce, and
>> therefore an LSP violation.
>> It sounds like you are suggesting that we instead spec
>> IterableAtLeastOnce, of which Iterable *would* be a credible subtype
>> -- but due to how Iterable is specified now, the problem is that
>> Iterable *already is* really "iterable at least once."  So there would
>> be no point in introducing this type; we already have it.
> Due to how Iterable is specified now it does not promise multiple
> iterations, but due to how most (all that I know of except
> DirectoryStream or some 3rd party) Iterables are implemented now, the
> common expectation is that it does. By implementing more Iterable(s)
> that don't support multiple iteration (regardless of whether they
> implement this new sub-type or not), this expectation will be less and
> less honored. Perhaps this is not so bad. At various occasions the
> specification has been changed to accommodate the long-standing behavior
> or expectation of behavior, but this seems not to be one of them.
> Let's pretend for a moment that Iterable specification was changed to
> guarantee multi-pass iteration. In that case the IterableAtLeastOnce as
> a supertype of multi-pass Iterable would make much more sense, wouldn't it?
> But as there could be Iterables out there that by current spec are
> perfectly valid and don't support multi-pass iteration, such spec change
> would make them non-conformant and is therefore not allowed. So I'm
> convinced now that this is the least-bad solution.
> Regards, Peter

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.


More information about the core-libs-dev mailing list