JSR 335 Lambda Specification, 0.9.0
Dan Smith
daniel.smith at oracle.com
Mon Jan 13 15:12:34 PST 2014
On Jan 7, 2014, at 3:22 PM, Stephan Herrmann <stephan.herrmann at berlin.de> wrote:
> (all this is about 18.5.2:)
>
> From the Changelog of 0.9.0:
>> Added rules to invocation type inference to special-case when the return type is an inference variable, and may end up either being wildcard-parameterized or requiring unchecked conversion.
>
> These changes are causing regressions in our implementation.
> I might have some other bugs lurking around, but could you please double check:
> Could some occurrences of R θ be intended to say R instead? Specifically these:
> - bullet 3.2: "Otherwise, if R θ is a parameterized type ..."
> - bullet 3.3: "Otherwise, if R θ is an inference variable α ..."
Yes. All this means is that the type has inference variables in it. (R, before substitution, is the declared return type of the method.)
> Additionally the use of erasure in bullet 3.1 causes grief.
> In experiments I do get better results using a raw type instead.
? Which raw type?
This isn't really new, but simply clarifying/preserving the rule from 15.12.2.6 that, if unchecked conversion occurred, the return type is the erasure. (See JLS 7.)
> Finally: it would be extremely helpful if you could give examples for
> the new bullets 3.3.1 and 3.3.2. So far I haven't a clue :)
<R> R m(R... args);
<T> void forEach(List<T> arg);
Bullet 3.3.1:
I noticed there's an error: bullet 3.3 should say that U is the _capture of_ the instantiation of alpha. Here are two examples:
forEach(m((List<?>) null));
Let 'r' and 't' be inference variables. Bounds B2 for m are { List<?> <: r, r <: Object }. It would be incorrect to assert that r -> List<t> -- in reality, the constraint is that the _capture of_ 'r' is a subtype of List<t>. So in this situation we eagerly resolve r = List<?>, perform capture, and then proceed with List<#CAP> -> List<t>.
forEach(m((ArrayList<Readable>) null, (LinkedList<Runnable>) null));
Bounds B2 for m are { List<Readable> <: r, List<Runnable> <: r, r <: Object }. Again, an error would occur if we required r -> List<t>, but there's no problem if we use lub to resolve r = List<?> and perform capture.
Bullet 3.3.2:
forEach(m((ArrayList) null));
Bounds B2 for m are { List <: r, r <: Object }. There would be an error if we asserted r <: List<t>. But if we eagerly resolve r = List, then we can do ArrayList -> List<t> and 18.2.2 can do its job by recognizing an unchecked conversion.
—Dan
More information about the lambda-spec-experts
mailing list