[Grace-core] [A Graceful Blog] Comment: "From Lancaster to Portland"

Kim Bruce kim at cs.pomona.edu
Tue Oct 11 15:29:06 PDT 2011


Hi,

This seems to have changed between the Java Language Reference, 2nd edition and 3rd edition.  Here is the specification in the Java Language Reference, 2nd edition (section 15.25):

"The type of a conditional expression is determined as follows:

	• If the second and third operands have the same type (which may be the null type), then that is the type of the conditional expression.
	• Otherwise, if the second and third operands have numeric type, then there are several cases:
		• If one of the operands is of type byte and the other is of type short, then the type of the conditional expression is short.
		• If one of the operands is of type T where T is byte, short, or char, and the other operand is a constant expression of type int whose value is representable in type T, then the type of the conditional expression is T.
		• Otherwise, binary numeric promotion (§5.6.2) is applied to the operand types, and the type of the conditional expression is the promoted type of the second and third operands. Note that binary numeric promotion performs value set conversion (§5.1.8).
	• If one of the second and third operands is of the null type and the type of the other is a reference type, then the type of the conditional expression is that reference type.
	• If the second and third operands are of different reference types, then it must be possible to convert one of the types to the other type (call this latter type T) by assignment conversion (§5.2); the type of the conditional expression is T. It is a compile-time error if neither type is assignment compatible with the other type."

The last bulleted item has been changed in the 3rd edition of the JLR to the following:

"	• Otherwise, the second and third operands are of types S1 and S2 respectively. Let T1 be the type that results from applying boxing conversion to S1, and let T2 be the type that results from applying boxing conversion to S2. The type of the conditional expression is the result of applying capture conversion (§5.1.10) to lub(T1, T2) (§15.12.2.7)."

Now the reference to capture conversion has only to do with generics and so can be ignored.  Section 15.12.2.7 essentially reduces to the fact that Java now implicitly supports intersection types (something that was a surprise to me!).  So if we have interface types A, B, C, & D such that A <: C,D and B <: C,D, while C and D are not in any subtype relation, then if a has type A (but not B) and b has type B (but not A) then boolExp?a:b is essentially given type C & D, and hence can be used as either C or D.

This is a rather significant change, and reflects the fact that at times you really, really need least upper bounds.  [They also refer to glb's in the reference because of contravariance needs.]

It's a bit strange that they introduced intersection types in the language reference, but not in the language, as it seems to go against the philosophy of nominal typing.  I suppose they found it OK as the programmer never sees these types.

It does go to show the need for lub's and glb's -- something that is trivial with structural subtyping, but requires intersection types with nominal typing.

So, sorry to give out-of-date info originally, but I'm happy to find out that it does work now (though I'll have to change my class examples!!).

Kim

P.S.  By the way the added complexity in the 3rd edition rules on typing show why technically you don't want to hack a together a type system to do generics that also includes the old erasure types -- and wild cards only made it worse!  The description is pretty impenetrable even with lots of commentary.  I understand the politics/business reasons for not changing the virtual machine, but it sure hurt the complexity of the language!

On Oct 11, 2011, at 4:19 AM, Eric Tanter wrote:

> Dear all,
> 
> On Sep 26, 2011, at 9:23 PM, Kim Bruce wrote:
>> In fact, as I now recall, we ran into this with an OOPSLA paper where we ran into problems with typing conditional expressions, and we found we needed the entire lattice.  Because Java has conditional expressions, but no sups or infs (because of nominal typing), they do not fully support subtyping.  If expT: A <: C and expE: B <: C then "boolExp? expT: expE" is not typable in Java, even though it clearly has type C.
> 
> I don't understand this -- the following:
> 
> C c = (x < 10) ? new A() : new B();
> 
> does type correctly in Java with A <: C and B <: C
> 
> am I missing something?
> 
> Thanks!
> 
> -- Éric



More information about the Grace-core mailing list