I read the definition as (ignoring the implementation):
return a Value or Absent when given an Iterable<Value,Absent> where Value is Comparable and Absent is Null
Correct me if I am wrong,
but there doesn't appear to be anything linking the nullability of the return value based on the possible emptiness of the input value. How does the compiler check this constraint (which sounds a lot like a dependent type relation)?Upon further reading of the Iterable type[2], I have more questions, does "Nothing" satisfy "Null"?
| If not, then it looks to me like passing in a non-empty iterable (Iterable<X,Nothing>) is a type error.
| If so then I would imagine that it becomes harder to enforce the constraint, likely because the return type can still be Null regardless of input restrictions. Does this use extra type inference on the expressions inside the function to do the enforcement, for instance using the "exists" operator to perform type set subtraction between {Value|Null} and {Null} on the true branch. This implies that if I re-write the max function to have a single exit point (`ret = Null; if (exists values.first) { ...; ret = ...; } return ret;`) then I don't get the same guarantees?
Also the fact that Null is referenced by the "exists" operator also implies that it is part of the language specification, and not actually definable in any meaningful way as a user type.
Digging a bit deeper, I was very disappointed to read this snippet [3]:
Nothing is considered to belong to the module ceylon.language. However, it cannot be defined within the language.
If I read correctly, that means that I cannot implement the same behaviour/enforcement with completely user defined types.[1]: http://modules.ceylon-lang.org/repo/1/ceylon/language/1.0.0/...
[2]: http://modules.ceylon-lang.org/repo/1/ceylon/language/1.0.0/...
[3]: http://modules.ceylon-lang.org/repo/1/ceylon/language/1.0.0/...