Help

Haha! Try compiling this Java code:

interface Interface<T> {}
class Bang<T> implements Interface<Interface<? super Bang<Bang<T>>>> {

    static void bang() {
        Interface<? super Bang<Byte>> bang = new Bang<Byte>();
    }
	
}

(For me, the compiler stackoverflows, and Eclipse asks for my permission to crash.)

I'm not sure how widely known this problem is. It's not really a bug in the compiler, more like a bug in Java's type system. I found out about it from this excellent paper, which also proposes a solution to the problem, but the paper appears to build on work in this other paper, which I'm also linking because I'm a big fan of Stefan Wehr's work on JavaGI.

UPDATE: Here's another paper dealing with this issue, this time from Microsoft guys.

And, in case you're wondering, yeah, I can make the Ceylon typechecker stackoverflow with the equivalent code:

interface Interface<in T> {}
class Bang<T>() satisfies Interface<Interface<Bang<Bang<T>>>> {}
void bang() {
    Interface<Bang<String>> bang = Bang<String>();
}

I guess ima gunna get right on to implementing the solution proposed in Tate et al.

9 comments:
 
16. Aug 2011, 13:40 CET | Link
John
Hi, I know it's totally off-topic but I haven't seen anything about exception handling in Ceylon (besides that union-types could be used as a form of checked exception). Will Ceylon be using the traditional try/catch/finally statement? How would you model throwable objects in Ceylon? I've always felt that having to extend the concrete java.lang.Exception class was a really big constraint in java. Could it be possible to mark throwable types with an annotation?
 
22. Sep 2011, 20:55 CET | Link
asookazian

plz answer above ? on exception handling.

also, will Ceylon have something similar to @synthesize in Objective-C which auto-generates getter/setter methods (IIRC groovy has similar concept for auto-generating getter/setter methods). thx.

 
22. Sep 2011, 23:05 CET | Link
Quintesse

Exception handling uses Java's try-catch-finally but no checked exception exist, only runtime.

And no need for @synthesize because implicit getters and setters are always available (and can be explicitly provided).

 
01. Oct 2011, 00:55 CET | Link
Arbi

what's the status on the Ceylon compiler?

 
10. Oct 2011, 08:34 CET | Link
John
Exception handling uses Java's try-catch-finally but no checked exception exist, only runtime.

Will you have to extend something like ceylon.lang.Exception to make your own exceptions or do you plan something more clever? (Such as not forcing people extending concrete classes.) Thanks.

 
10. Oct 2011, 20:37 CET | Link
John wrote on Oct 10, 2011 02:34:
Exception handling uses Java's try-catch-finally but no checked exception exist, only runtime.
Will you have to extend something like ceylon.lang.Exception to make your own exceptions or do you plan something more clever? (Such as not forcing people extending concrete classes.) Thanks.

Yes, you extend Exception from ceylon.language, which has some pretty complex rules in terms of what it actually compiles down to at the bytecode level. Tom put a bunch of work to get this stuff right.

 
22. Feb 2012, 07:04 CET | Link
lvilnis

Hi, I'm curious - how is the Ceylon code the equivalent of the Java code? It seems right to me that it should be and I've been trying to figure out exactly why. The Java code and paper appeared to depend on a defect in wildcards, and your example doesn't use wildcards - just inheritance. The Java example appears to be doing something funky where it declares a type bounded by itself... the Ceylon code just inherits from itself passed through a type constructor a couple times. It looks like the Ceylon version of the bug is more of an issue in how the compiler type-checks generics. I will admit that I only skimmed the paper so it could be I'm asking a really dumb question.

 
22. Feb 2012, 15:53 CET | Link
your example doesn't use wildcards

Ceylon has declaration-site variance, so it is equivalent to the use of wildcards in Java. (Interface has a type parameter declared in.)

 
22. Feb 2012, 22:48 CET | Link
lvilnis
Fun! I ran the equivalent code in C# and the compiler gives the error "An expression is too long or complex to compile". Subtyping + polymorphism is hard. I'm definitely surprised that you get this error with plain old declaration-site variance, given that declaration-site variance is sort of standard in F-sub (in TAPL at least) and wildcards require some extra existential type machinery that seemed suspect. I always figured the stripped down, mostly-nominative form of subtyping in C#/Java would have ruled out the nasty non-termination issues of full F-sub. Thanks for the informative post and response!
Post Comment
Name:
E-mail address (optional):
Homepage URL (optional):
Subject:
Help
Let me type some plain text, not markup
Enable live preview
Enter characters (ignore circles):