But Kotlin? Since when does Kotlin have pattern matching with exhaustive checks? Also it does not have an `Maybe a` / `Option[A]` type out-of-the box.
But Kotlin? Since when does Kotlin have pattern matching with exhaustive checks? Also it does not have an `Maybe a` / `Option[A]` type out-of-the box.
sealed class Communication
data class Email(val emailAddress: String) : Communication()
data class Shouting(val preferredName: String) : Communication()
object HiveMind : Communication()
fun exhaustiveWhen(comm: Communication) {
// not exhaustively checked (will compile)
when (comm) {
is Email -> println("sending email to ${comm.emailAddress}")
}
// *is* exhaustively checked (error at compile time)
// must add HiveMind or 'else' branch
val result = when (comm) {
is Email -> println("sending email to ${comm.emailAddress}")
is Shouting -> println("HELLO, ${comm.preferredName}!")
}
// *is* exhaustively checked
when (comm) {
is Email -> println("sending email to ${comm.emailAddress}")
is Shouting -> println("HELLO, ${comm.preferredName}!")
}.let { }
}Even the syntax can be made less awkward[1] this look still like a wonky hack to me where the user can do way to much wrong.
[1] https://proandroiddev.com/til-when-is-when-exhaustive-31d69f...
Whether a type is nullable or not is a property of the type. This creates more or less two mirror universes of types, and you can't mix even "the same" types from that incompatible universes.
An Option type is on the other hand side a distinguished parametric type on its own (I wrote `Maybe a` / `Option[A]` for a reason). It can "wrap" arbitrary other types without "infecting" those with the nullability property. Being a proper parametric type makes `Maybe` / `Option` also "just a type constructor". Therefore it can be composed with other types and type constructors according to common rules. `Maybe` / `Option` doesn't require any special rules in the language (which would make the language more difficult to learn and use)!
Also `null` is very different form `Empty` / `None`: A null value can still "sneak in" through arbitrary references and cause run-time errors if one has to interoperate with a "null unsafe" language or system (and that's more or less "the whole universe" out there). A `None` can not "sneak in" as it can be only assigned to something of `Option` type. Sure this doesn't solve the "null problem" as such but one can at least distinguish the cases where the model value is really optional, and the cases where one needs to deal with `null`s coming (potentially) form the outside world. In the one case one will use the Option type throughout the rest of the program, in the other case one will preform some null-check as early as possible and "unwrap" the underlying none-null value to work with it directly thereafter.