[concurrency-interest] CompletableFuture in Java 8

thurstonn thurston at nomagicsoftware.com
Fri Dec 12 15:44:02 EST 2014


√iktor Ҡlang wrote
>> Hello Viktor,
>>
>> Although this may seem a digression, I'm curious whether you object to
>> something like Collectors#toList() in j.u.stream?
>>
>> Because this facilitates (I wouldn't say encourages) code like the
>> following:
>>
>>
>> List
> <T>
>  l1 = . . .
>> List
> <T>
>  l2 = l1.stream().filter(...).collect(toList())
>>
>> List
> <T>
>  l3 = l2.stream().map(...).collect(toList())
>>
>> for (T : l3)
>>   do something
>>
>> Now, we can all agree that the code above is awful, even wrong, but is
>> it's
>> possibility (well, probably more than possibility - I've actually seen
>> such
>> code) enough to warrant the exclusion of Collectors.toList()?
>>
> 
> At least that code doesn't impact liveness of the system. (well, you can
> still OOME, but you can do that by allocating an array, so that's not
> really the same)

Frankly, I don't understand "impact liveness of the system" - the classical
definition of liveness is "a guarantee that each thread (process, etc) will
*eventually* succeed" -
Doesn't a (hypothetical) CompletionStage#get() offer the same liveness
guarantee as any of the "terminal operations" on Stream?
In fact, IFAICT, Stream#collect() can indeed block (probably does for
parallel streams), that's an implementation detail, and doesn't really
change the semantics of the program (of course the JVM could crash, or the
scheduler might never again schedule a thread, etc., but let's hand-wave
those away)

What I was really asking (not very well in retrospect), is if you wouldn't
prefer the Stream api to have its terminal operations return CompletionStage
(or some rump)?, i.e. your objection isn't restricted to just narrow
questions of blocking/not-blocking, but mixing "reactive"-style programming
(or as you termed it "async monadic-style programming") with imperative
style  


√iktor Ҡlang wrote
>> Of course the issue isn't exactly one of "encouraging blocking" (unless
>> the
>> streams were parallel) . . .
>>
>> I guess I think that "discouragement by difficulty" in API design more
>> often
>> than not leads to grief (which is not to say that I've never done it)
>>
> 
> Do you have any example?

Not sure what you're asking here -- but (assuming there was no
#toCompletableFuture()), your code on implementing a "blocking get" on a
CompletionStage is a prime example; that's certainly not the only way (as an
aside I played around with a cursory alternative approach and soon got
myself into trouble).

The point being, that if we can agree that many developers will want it (I
think that's undeniable), it's better to leave the implementation
encapsulated in the implementing CompletionStage class than have the
numerous adhoc approaches that inevitably result.
And put in the necessary admonitions in the JavaDoc



--
View this message in context: http://jsr166-concurrency.10961.n7.nabble.com/CompletableFuture-in-Java-8-tp11414p11626.html
Sent from the JSR166 Concurrency mailing list archive at Nabble.com.



More information about the Concurrency-interest mailing list