Could you please explain how the internal representation of null in the language's type system has any effect on the semantics of code written in that language?
Sure. So I'll give you one very over-simplistic example. Let's assume that T is an unknown type (a type parameter).
You can form types like Object&T, and if T is an optional type of form S|Null, then that is reduced automatically to the type S by the typechecker. But if T is not an optional type, then it just remains T.
Very useful to be able to do this kind of trick in generic code.
And note that nothing here was using any special reasoning about Null: this is all just the totally generic reasoning for union types in general.
Null in Ceylon is just another type, and nullable-X is just another union type, so you can use them sensibly with generics. With Kotlin if you want to write a generic method like "add two values" and have it handle nullness polymorphically then you have to think about it.
You can form types like Object&T, and if T is an optional type of form S|Null, then that is reduced automatically to the type S by the typechecker. But if T is not an optional type, then it just remains T.
Very useful to be able to do this kind of trick in generic code.
And note that nothing here was using any special reasoning about Null: this is all just the totally generic reasoning for union types in general.