The philosophy of Nothing

Reinier Zwitserloot reinier at
Mon Nov 30 02:23:13 PST 2009

The need for Nothing is really quite simple. If I have the sort method:

Collections.sort(someStringList, some instance of Comparator<String>)

and I wish to call it like so:

Collections.sort(someStringList, #(String a, String b) {
    throw new IStillNeedToImplementThisException();

then I should be able to. Do you wish to argue that the java compiler should
REFUSE to compile this code? If so - why? It's legal just about everywhere
else. However, without resorting to target typing, which BGGA/CFJ aren't
based on, the compiler cannot figure out that this closure returns 'int'. It
never returns, so, as return type means: "I guarantee that this method will
NOT return something that is NOT [my return type]", it can infer absolute
any type, and that rule will hold, because the method never returns. If I
inferred void, then you'd get an error that #(String, String)void is not
compatible with the required Comparator<String>, and that would be cryptic.

That's bad, so, the compiler would refuse to compile this with an error
saying that it can't figure out what you're trying to return. Given that
this it doesn't even matter, this is even more cryptic.

That's bad, so BGGA/CFJ needs a Nothing type so it can first consider this a
closure of #(String, String)Nothing, and then automatically 'box' this
closure into the required Comparator<String> (required signature: #(String,
String)int), as Nothing is a valid alternative for anything else. Including

--Reinier Zwitserloot

NB: Of course, *WITH* target typing, lack of the Nothing type is not nearly
as painful.

On Mon, Nov 30, 2009 at 7:41 AM, Paul Benedict <pbenedict at> wrote:

> Zdenek,
> Thank you for your patience. Is this use case any different than
> reflection or dynamic languages? It sounds like the "Nothing" type
> returns an Object and automatic casting is performed. So why don't we
> just use Object as the return value and force a cast?
> Paul
> On 11/30/2009 12:33 AM, tronicek at wrote:
> > They should compile because Nothing (the type inferred) is a subtype of
> > Integer and String.
> > If the type inferred was void, they should not have compiled.
> > So, Nothing enables the compiler to check types as it does in any other
> > cases.
> >
> > Another example:
> >
> > static<T>  T m(#T() p) {
> >    return p.invoke();
> > }
> >
> > Integer i = m(#() { throw new AssertionError(); });
> > String s = m(#() { throw new AssertionError(); });
> >
> > new ArrayList().add(#() { throw new AssertionError(); });
> >
> > Z.
> >

More information about the coin-dev mailing list