Saying about Kotlin 1.1 features, usage of underscores for unused parameters can be useful - as well as short and clear - if we’d like to check what branch to execute by partial set of object’s properties.
You basically want when to do the full blown pattern matching that Scala offers, but that is one of the features that JB decided was too complex (and probably really hard to implement).
While this will technically work it is not very efficient as it creates throw away objects for comparing.
I certainly agree that there are some definitely needed improvements to when, I don’t think we want full blown pattern matching.
Pattern matching is one the best things about Scala, and it’s something that’s easy to understand while being extremely useful. Sometimes I think people think all features of Scala are over complex functional programming idioms. While there are features that maybe fit into that category, pattern matching is not one of them. When I re-wrote a Scala library in Kotlin, the lack of pattern matching was the biggest annoyance to me.
In pattern matching you can a) match against values inside a structure (hence the term) and b) extract values from the matched expression.
So if we had a data class called Person, we could do
when(person) {
Person("sam", age) -> println("This matches all sams and makes $age available as a parameter")
Person(name, _) -> println("This matches all persons, and makes $name a parameter and ignores the age")
}
and various combinations of that kind of thing.
In Scala if you use a literal, then it will be matched against that value, if you use a variable name it will extract the value and assign it to the variable, and if you use a variable name inside backticks it will match against the value of an already defined variable (but that variable must be ‘constant’).
I’ve been using Kotlin and Rust side by side for a while now, and have really missed proper pattern matching from Rust, while missing proper IDE support from Kotlin
I don think that full blown pattern matching would be absolutely necessary. When can already do a lot of powerful things. What I’d like to see especially is something like this
when(thing) {
is Pair(a, b) -> { }
is OtherDataClass(a, _, c) -> {}
}
In that case, all that’d need to do is desugar it to a traditional data class destructuring.
when(thing) {
is Pair -> {
val (a, b) = thing
}
is OtherDataClass -> {
val (a, _, c) = thing
}
}
Would make that sort of code look much nicer, imo.
Having something like but not really pattern matching feels so off to me, especially in the presence of sealed and data classes. I couldn’t believe it and kept searching for what I was doing wrong. Finding out that it’s just not there in Kotlin was a big disappointment; the advantages of pattern matching in terms of explicit brevity are so big that its lack is noticeable.
I keep comparing Kotlin to Swift, and Swift has pattern matching for enums with associated values (which are really ADTs). The Scala approach to implementing it on top of the JVM seems prudent to me.
I’d appreciate some clarification about what was deemed “too complex”. The implementation in the compiler? The language feature for programmers?
I shifted some things around in my head and in a scratch, and I think pattern matching could be an additive, mostly-sugar extension. That is, programmers wouldn’t have to deal with it unless they want to, and huge parts of the implementation beyond desugarisation might be covered by the existing compiler. I’m sure I’m missing things, but I don’t understand why this is apparently not a discussion worth having.
I share exactly the same thoughts, and I’m also coming from a Swift background.
If programming complexity is an issue, Swift being open source, compiler programmers could take a glance at what was done in Swift
Yes, please, I miss pattern matching. +1 to what sksamuel and marikka said above.
IMO, destructuring is one of those “Aha!” moments in programming that is hard to do without once you’ve gotten used to it. And several other languages do have programmers getting used to it. So true matching would be awesome, but even if it were only allowed to go one level deep, binding names to parts would really improve the ergonomics of when usage.