Return type of max{} in Ceylon

117 views Asked by At

I get why the inferred return type of max({}) is Null (and I think it's awesome how that function works with empty/possibly-empty/non-empty iterables), but why is using an empty named argument list—max{}—inferred to return Nothing? Why are those cases different? Is that intended?

This compiles and runs just fine,

Nothing foo = max{};

although I would've expected it to fail immediately if it actually evaluated nothing. Since Nothing is the subtype of everything, you can even do this,

Integer bar = max{};

and the compiler won't complain, but running that produces a java.lang.NullPointerException. What?! I thought we were never supposed to see that in Ceylon!

1

There are 1 answers

2
Gavin King On BEST ANSWER

Wow, nice one! It took me a few minutes thinking to understand what is going on here. So, as I guess you know, this:

max {}

Is supposed to be, in theory, the same thing as these:

max({})
max { values={}; }

Now, if you write either of those permutations, you will get the correct return type Null inferred for max(). And, indeed, if you execute either example, the result is, correctly, null.

Indeed, even if I run the following program:

void run() => print( max{} );

It prints <null>, as we would expect.

So what's going on here is that I have a bug in my type argument inference algorithm, where it fails to take into account the "implicit" empty iterable argument, a {Nothing*}, when inferring type args. Therefore, you're getting the inferred type Nothing for both type parameters of max(), because the type parameters are treated as unconstrained. Then, since Nothing is a subtype of Integer, the typechecker lets you assign the result to Integer. Of course the null value that is actually returned by the function is not assignable to Integer, so you get an NPE that of course should never happen.

The solution is I need to fix the bug. It will be a tiny one liner.

If you don't mind, would you submit a bug report to ceylon-spec please, and I will fix it tomorrow.

Thanks!