On Apr 15, 2013, at 1:37 PM, Martin Buchholz <[email protected]> wrote:
> CompletableFuture currently has a method like this:
>
> public CompletableFuture<Void> acceptEither
> (CompletableFuture<? extends T> other,
> Consumer<? super T> block) {
> return doAcceptEither(other, block, null);
> }
>
> But that signature is not quite correct (not as general as it could be). The
> "correct" signature is
>
> public <U super T> CompletableFuture<Void> acceptEither
> (CompletableFuture<? extends U> other,
> Consumer<U> block) {
> return doAcceptEither(other, block, null);
> }
>
> but that fails to compile, because type parameters can only be constrained by
> extends, not super. Is implementing this on the radar?
My favorite example:
interface Optional<T> {
<S super T> S get(S alternate);
}
Optional<Integer> o = ...;
Number n = o.get(0.0);
We were _this_ close to adding this, or something like it, with Lambda. In the
end, it didn't make the cut.
The good news is that capture variables already have lower bounds, and
inference in Java 8 has been enhanced quite a bit, such that it can mostly
handle things like this. So it seems like it would be a relatively modest task
to support the feature someday.
> Angelika claims
> "lower bounds for type parameters make no sense"
> http://www.angelikalanger.com/GenericsFAQ/FAQSections/TypeParameters.html#Why%20is%20there%20no%20lower%20bound%20for%20type%20parameters?
>
> but I am finding that hard to believe. Is she right?
Lots of people said a lot of wrong things about generics in the heady Java 5
days. One or two of those things even ended up in the language spec. :-( But
no, "I can't think of why this would be useful" does not imply "this makes no
sense." (To be fair, I think we all make that leap from time to time.)
> For comparison, the equivalent static method can be made to do what we want:
>
> public static <U> CompletableFuture<Void> acceptEither
> (CompletableFuture<? extends U> f,
> CompletableFuture<? extends U> other,
> Consumer<U> block) {
> return ...
> }
Yep, that's the workaround for now. Or use a weaker signature for your
instance method. (Or both.)
On Apr 17, 2013, at 3:53 PM, Martin Buchholz <[email protected]> wrote:
> With the coming of lambda, it is more likely that people will be creating
> APIs with "not quite correct" generic types, as we are doing in
> CompletableFuture. Which is pretty bad for a feature that is designed
> specifically to provide compile time safety.
True. I've made that argument for other axed features as well -- we punt now,
and solving the problem later will just be harder, due to further compatibility
constraints. Ultimately, it would be great to make everything perfect out of
the gate; but that's not practical. (And in fact, "out of the gate" in this
case was 9 years ago.) Besides, we have to have something fun to do next time.
:-)
—Dan