Java 8 language spec flaw/bug
Brian Goetz
brian.goetz at oracle.com
Thu Aug 21 16:46:46 UTC 2014
> Apologies if this is the wrong place for this.
For the record, now that Project Lambda has concluded, the right place
for these comments is probably the newly-created:
jls-spec-comments at openjdk.java.net
It's also fair play to post your comments in the bug record (if you have
sufficient access rights in OpenJDK.)
But, the relevant people are also here, so carry on...
>
> I'm concerned with this bug:
> https://bugs.openjdk.java.net/browse/JDK-8044053
>
> It concerns changes in the language spec (and the compiler) that cause
> some backwards incompatibility between Java 7 and Java 8. The example in
> the bug ticket uses the trinary conditional operator but I believe this
> is a red herring, that is, the same problem occurs when not using the
> conditional operator. Specifically, the following compiles with Java 7
> but not 8:
>
> |--- begin ---
> public class Foo {
>
> public static void main(String[] args) throws Exception {
> // compiles fine in Java 7 and Java 8:
> Class<? extends CharSequence> aClass= ternary(true,
> String.class, StringBuilder.class);
> CharSequence foo= foo(aClass);
>
> // Inlining the variable using 'ternary' method
> // Compiles with Java 7 but not with 8:
> CharSequence foo2= foo(ternary(true, String.class,
> StringBuilder.class));
> }
>
> static <T> T foo(Class<T> clazz) throws Exception {
> return clazz.newInstance();
> }
>
> static <T> T ternary(boolean cond, T a, T b) {
> if (cond) return a;
> else return b;
> }
> }
> --- end ---
> |
>
>
> I'm worried about the comments in the bug, but I'm unable to make
> comment myself (I don't have an OpenJDK account and it doesn't appear to
> be possible for general members of the public to sign up). See Dan
> Smith's comment:
>
>> In general, the use of context provided by the new strategy is
>> valuable, but in this case it interferes with the opportunity for
>> capture. It might be possible to use a strategy similar to 18.5.2 in
>> order to recognize situations in which eager bottom-up typing and
>> capture is the more useful approach. Ultimately, this comes down to
>> whether we consider the conditional expression to be a poly expression
>> or not (see 15.25.3). (But changing the simple rule, "A reference
>> conditional expression is a poly expression if it appears in an
>> assignment context or an invocation context," to something more
>> complex may not be worthwhile.)
>
> This is, in my opinion, bogus. The problem is not in how conditional
> expressions are treated at all - as I have demonstrated above, the
> problem also occurs with generic methods. In fact the issue is with
> section 18.2.3 of the JLS:
>
> --- begin ---
>
>
> 18.2.3. Subtyping Constraints
>
> ...
>
> A constraint formula of the form ‹S |<=| T›, where S and T are type
> arguments (§4.5.1
>
> <http://docs.oracle.com/javase/specs/jls/se8/html/jls-4.html#jls-4.5.1>),
> is reduced as follows:
>
> If T is a type:
>
> * If S is a type, the constraint reduces to ‹S = T›.
>
> --- end ---
>
>
> This turns a 'contains' constraint directly into an 'equals' constraint,
> which is precisely what causes the problem. I can see no justification
> for this. It should instead imply a sub-type constraint, that is, it
> should reduce to ‹S |<:| T›. At this point the problem goes away,
> without - as far as I can see - having any negative impact on the
> enhanced type inference that Java 8 provides. Instead of getting two
> conflicting equality constraints for the T in the Foo example above
> (T=String and T=StringBuilder), we would get two subtype constraints
> (String <: T and StringBuilder <: T), which from a theoretical
> perspective is perfectly correct.
>
> Section 18.4 then details how to resolve the two constraints and applies
> the lub function, just as would be done in the Java 7 language spec.
>
> Am I crazy? It seems fundamentally obvious to me that a contains
> constraint shouldn't be turned into an equality constraint, but everyone
> else involved seems to be overlooking that. I'd appreciate if someone
> can either set me straight, or add an appropriate comment to the ticket
> at https://bugs.openjdk.java.net/browse/JDK-8044053. I'd hate to see
> this getting "fixed" by changing "whether we consider the conditional
> expression to be a poly expression or not".
>
> Thanks,
>
> Davin
>
>
>
>
More information about the lambda-dev
mailing list