Does Kotlin compiler verify that match block is exhaustive as in Scala?

Hello,

last time I checked this out in Kotlin it was not the case as far as a I remember. Now I work on a Scala project (I like Kotlin much as well, but it happens to be a Scala project) where we make use of Scala match blocks where the Scala compiler can verify that the match block covers all possible cases. For this particular type of application this is very valuable, because a missing case in a match block may result in true accidents, and I’m therefore really glad that Scala has this.

My question is whether Kotlin has this (meanwhile) as well. If not I really suggest to put it in. The load on the compiler to verify that all leaves of the match block are covered seems not to be that high.

Here is an example to explain what I mean:

val foo: Optional<Boolean>
val bar: Optional<Boolean>

(foo, bar) match {
      case (None, None) => Some(UNKNOWN)
      case (Some(true), Some(true)) => None
      case (Some(false), Some(true)) => None
      case (None, Some(true)) => None
      case (Some(true), Some(false)) => Some(FAILED)
      case (Some(true), None) => Some(UNKNOWN)
      case (Some(false), Some(false)) => None
      case (Some(false), None) => None
      case (None, Some(false)) => Some(UNKNOWN)
}

If any of the case statements above where missing, the Scala compiler would complain. Question is whether this is also the case for the Kotlin compiler.

If we use when as an expression, then it is exhaustive and it is checked for correctness at the compile time. But it is hard to discuss an example like above, because Kotlin doesn’t have (yet?) as advanced pattern matching as Scala, so the above code is not really translatable to Kotlin.

3 Likes

It would be really good if Kotlin also had pattern matching where the compiler verifies that the match block is exhaustive and that also works on compound types.

I know the Kotlin guys are very careful not to add features that make the compiler slow and that is for a very good reason. But this feature is really needed. I work on a safety critical application where accidents in the real live can happen if a case is missing in the pattern match block. I’m therefore really happy that Scala has it. However, the Scala is really slow. We are using Scala 3 from the beginning. The compiler is still really slow and also the incremental compiler is slow. Spending a lot of time waiting for the incremental compiler.

If Kotlin also had pattern matching on compond types with the compiler checking for missing cases I would change to Kotlin immediately without thinking about it at all, because the Scala compiler is so slow, also in Scala 3. I just want to get the message passed through to the Kotlin language implementors that this specific Scala feature is not academic and Kotlin having it as well would make many people switch from Scala to Kotlin.

By the way, Rust has exhaustive pattern match checking as well. It seems like it can be implemented without slowing down the compiler all that much.

1 Like

Tbf you can force the exhaustive pattern matching in the when block by assigning the result to an unused variable. Of course it would be better if the language supported this, but there is a work around.

val forceAllPaths = when (someCondition) {
    path1 -> value()
    path2 -> otherValue()
    else -> throw RuntimeException("oh no!")
}

Regarding the complex pattern matching… idk why Kotlin doesn’t have it, and idk if they’re ever going to add it. I sort of suspect that if it’s not in the language by now, they’re not going to add it… it seems like a very structural part of the language, and the changes they’re doing now don’t really seem to be changing structural parts or adding keywords. But I could be wrong. I hope I’m wrong, cause it’d be a powerful feature. :slight_smile:

1 Like

Doesn’t Scala’s pattern matching depend upon having apply()/unapply() and all the relevant infrastructure? I’m guessing that adding it to Kotlin would require a shedload of similar stuff to be added, potentially breaking a lot of existing code.