JSR 335 Lambda Specification, 0.6.2
daniel.smith at oracle.com
Mon Apr 1 11:01:48 PDT 2013
On Apr 1, 2013, at 10:15 AM, Stephan Herrmann <stephan.herrmann at berlin.de> wrote:
>> But in the mean time, whatever you were doing for Java 7 should continue to work as an approximation, and I wouldn't expect any regressions.
> I should have mentioned that I observed these regressions *after* doing
> a best guess as to which part of the old implementation might come
> closest to what we need here. Close, but no cigar. I'm not surprised
> by the mismatch given that the functional breakdown in the existing
> Eclipse compiler implementation is probably quite different from the
> code you are looking at.
> Looking deeper into those tests that make this approximation fail
> I see that most of these involve a raw type in the position of the
> sub type (S).
> Could you please give an advance statement how 18.5.5. will be
> integrated into 18.2.3 and friends? More specifically, if unchecked
> conversion is involved, should this be computed by a separate/nested
> invocation of the inference, or should a set of additional bounds
> and constraints be added to the current inference?
Okay, so it sounds like your problem is in handling cases like:
<T> void m(List<T> arg);
m(new ArrayList()); // raw type
JLS 7: An initial constraint of the form "ArrayList << List<T>" is produced (188.8.131.52); no inference constraint is implied (184.108.40.206); but the method is applicable by subtyping, which allows for an unchecked conversion (220.127.116.11).
Lambda Spec 0.6.2: An initial constraint of the form "new ArrayList() -> List<alpha>" is produced (18.5.1); this reduces to "ArrayList -> List<alpha>" (18.2.1); as noted in 18.2.2, handling an unchecked conversion here is a to-do item.
Nothing substantial has changed here -- just the framework surrounding the problem. In JLS 7, we're happy to produce unsound results (a raw type targeting a parameterized type always gets you no new bounds, which effectively means "true"). In the Lambda Spec, the goal is to tighten that up by producing "true" or "false" depending on whether the conversion will be deemed legal or not.
The problem with being precise about when an unchecked assignment is allowed by inference is that the spec has always been vague about when it is allowed at all -- 5.1.9 says an unchecked conversion is to "any parameterized type of the form G<T1,...,Tn>" -- that's nondeterministic, and asking for trouble. Hence, I've toyed with 18.5.5, although that shouldn't be taken too seriously until we figure out how to plug it in. In the mean time, javac and Eclipse have both traditionally just defined what constitutes a legal unchecked assignment on their own, presumably with much less complexity than using type inference (18.5.5), and probably not consistently with each other.
So, short answer: however you test for legal unchecked assignments -- do the same check for "ArrayList -> List<alpha>" to get a "true" or "false" result. (Yes, an inference variable is not a type, but given the existing vagueness, just making it work somehow would get a reasonable approximation.)
In the next spec iteration, we'll have a more concrete plan on how to plug in 18.5.5 or use some other strategy to decide whether an unchecked assignment is legal, and maybe even get some extra bounds out of the deal in certain corner cases.
> So, yes, the spec is basically implementable, but, no, it doesn't work.
> Or, sorry, it may work for some 70 percent of the interesting programs,
> but not close to any of the many nines we are striving for.
> As I see little benefit in building the new implementation on new
> guess work, I'll basically just wait for the next version of the spec.
Given that this area is already built on guess work, I don't see the lack of clarity so far as a fatal flaw.
Yes, I'd like to clear up some of the ambiguity here. In the mean time, it's useful to know that this particular issue is one that caused you some trouble. If there are other areas, please keep asking, and I'll happily describe our current thinking and identify things that are still unresolved.
A new spec is a few weeks away. Hard to say exactly how many "a few" is. The issue right now is _solving_ problems like this; writing down the solutions comes next.
More information about the lambda-spec-observers