>Fair point for nullables, although that is already possible through annotation processing (see the checkers framework) - but there is a good faith argument that this isn't "core" enough.
It also wasn't available in a practically usable form until relatively recently (when talking about history), so my very first point about the timeline of languages still stands. Plus it adds even more verbosity to an already very verbose language.
>The syntax for functions
I meant function types, e.g. the variable `val a = {}` has a type `() -> Unit`, which is a real type in Kotlin.
Of course you can achieve a similar thing in Java with SAM interfaces (including all the weirdly named ones in `java.util.function`), so I'd call that the same level of expressiveness.
I don't see why `inline` wouldn't be a part of the type system, when you can have a function argument (that is itself a function) that either
- can be passed into anything that expects a function as an argument - as long as the rest of the type matches of course (a non-inline argument)
- can only be invoked or passed into another inline function (an inline argument)
Conceptually, this has some parallels to C++'s const-correctness ("any matching pointer can go here" vs. "only a non-const pointer can go here", "this function cannot be called via this pointer" etc.), which is generally considered a part of its type system.
It's just a matter of definition really.
>Sum types, really you can have that with just inheritance (base class with package private constructor + final sub-classes).
The person that uses those classes (I'll call them consumer), e.g. writes a function that takes the base class as an argument, then has to be aware of the internal implementation - the compiler won't help you there. If someone else who maintains that part of code adds a new subclass, you'll have an unaccounted for possibility and there is no way to safeguard against that (unless you redesign the whole part of the codebase using crutches like the visitor pattern).
There is no good way to express "this value can be one of these types, but no other" in Java's type system from the consumer's point of view (only from the producer's). I may not be using the correct terms here but hopefully you get what I mean. As far as the Java compiler knows, you are not really expressing a sum type, and that comes with the mentioned negative consequences.
It also wasn't available in a practically usable form until relatively recently (when talking about history), so my very first point about the timeline of languages still stands. Plus it adds even more verbosity to an already very verbose language.
>The syntax for functions
I meant function types, e.g. the variable `val a = {}` has a type `() -> Unit`, which is a real type in Kotlin.
Of course you can achieve a similar thing in Java with SAM interfaces (including all the weirdly named ones in `java.util.function`), so I'd call that the same level of expressiveness.
I don't see why `inline` wouldn't be a part of the type system, when you can have a function argument (that is itself a function) that either
- can be passed into anything that expects a function as an argument - as long as the rest of the type matches of course (a non-inline argument)
- can only be invoked or passed into another inline function (an inline argument)
Conceptually, this has some parallels to C++'s const-correctness ("any matching pointer can go here" vs. "only a non-const pointer can go here", "this function cannot be called via this pointer" etc.), which is generally considered a part of its type system.
It's just a matter of definition really.
>Sum types, really you can have that with just inheritance (base class with package private constructor + final sub-classes).
The person that uses those classes (I'll call them consumer), e.g. writes a function that takes the base class as an argument, then has to be aware of the internal implementation - the compiler won't help you there. If someone else who maintains that part of code adds a new subclass, you'll have an unaccounted for possibility and there is no way to safeguard against that (unless you redesign the whole part of the codebase using crutches like the visitor pattern).
There is no good way to express "this value can be one of these types, but no other" in Java's type system from the consumer's point of view (only from the producer's). I may not be using the correct terms here but hopefully you get what I mean. As far as the Java compiler knows, you are not really expressing a sum type, and that comes with the mentioned negative consequences.