Loose end: spliterator() and stream() methods on Iterable
Remi Forax
forax at univ-mlv.fr
Mon Jun 24 14:41:57 PDT 2013
On 06/24/2013 09:40 PM, Brian Goetz wrote:
> After further thought, I think what this means is that we can move
> spliterator() up to Iterable, but not stream(). The reason for this
> is that some classes that implement Iterable<Integer> might prefer
> that their stream() method return an IntStream, not be forced into a
> Stream<Integer>. So putting stream() too high up in the hierarchy
> forecloses on this.
I agree,
Spliterator.OfInt is a Spliterator but IntStream is not a Stream.
Rémi
>
> On 6/14/2013 3:12 PM, Brian Goetz wrote:
>> In trying to work this one out, I ran into a snag with our test code.
>>
>> We have some test code that looks like:
>>
>> public interface TestData<T, S extends BaseStream<T, S>>
>> extends Iterable<T> {
>> S stream();
>> S parallelStream();
>> ...
>> }
>>
>> with specializations:
>>
>> public interface OfRef<T> extends TestData<T, Stream<T>> { }
>> public interface OfInt extends TestData<Integer, IntStream> { }
>> ...
>>
>> The idea is that the stream() method on TestData.OfRef returns a
>> Stream<T>, and on a TestData.OfInt it returns an IntStream. With stream
>> methods on Iterable, this causes a conflict.
>>
>> Of course, I can change my test code. But it illustrates the danger of
>> adding stuff to "top-level" interfaces like Iterable -- the risk for
>> conflict increases dramatically because so many things implement it.
>>
>> Here, the root cause is that I want stream() to be a type-specific
>> method. This definitely falls into the "advanced generics tricks"
>> category, but being able to do this definitely reduced a lot of
>> duplication in our code base, and I can't imagine I'm the only one who
>> might want to do it.
>>
>> On 6/10/2013 6:19 PM, Brian Goetz wrote:
>>> This is one that everyone seems in agreement with (in theory) but which
>>> we never get to convergence on. Given how the API has shaken out, it
>>> seems sensible to:
>>>
>>> - Add spliterator() to Iterator, with a default implementation of
>>>
>>> return Spliterators.spliteratorUnknownSize(iterator(), 0)
>>>
>>> - Move the existing stream() and parallelStream() methods up from
>>> Collection to Iterable, as is (they are implemented entirely in
>>> terms of
>>> spliterator() and public factories)
>>>
>>>
>>> When this last came up, there was concern that the spec of
>>> Iterable.stream() would be exactly as fuzzy as the spec of
>>> Iterable.iterator(). I think the best we can do is add an
>>> implementation note that if iterator() indeed gives you a fresh
>>> iterator
>>> every time, then stream() gives you a fresh stream every time, and
>>> otherwise unpredictable results will follow. It would be nice to
>>> further note that subtypes of Collection are better behaved, but sadly
>>> the spec for iterator() in Collection is no better than in
>>> Iterator! We
>>> can further add a "recommendation" to Iterable.iterator() to suggest
>>> that Iterable implementations are encouraged to do this, but
>>> otherwise I
>>> think this ship has sailed.
>>>
>>>
More information about the lambda-libs-spec-experts
mailing list