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