https://kotlinlang.org logo
l

Leon K

12/05/2019, 4:17 PM
I'd love to discuss true pattern-matching in Kotlin again. I know, the current stance of jetbrains is "No, no pattern matching, it's to complicated to implement and to complex syntactically to fit kotlins vision" But i'd still like to discuss it more. Do you think it would help Kotlin to have rust / scala-style pattern-matching and destructuring? if not, why not?
👍 1
s

sean

12/05/2019, 4:26 PM
Coming from F# I miss active patterns, and more advanced feature. I'm not sure if it's planned. But this may be better served under the new arrow meta compiler.
1
l

Leon K

12/05/2019, 4:41 PM
i do miss them as well. as i said, i dont think theyre planned, because they're deemed "to complex"
s

sean

12/05/2019, 4:47 PM
Agreed I don't think it will get into core. Maybe an additional library. I know arrow has had requests for advanced pattern matching.
l

Leon K

12/05/2019, 6:40 PM
i think that advanced pattern matching really is a lot to ask of a compiler plugin. this should, if at all, really be added to t he language. it would be a to big step to just add in a library
e

elizarov

12/06/2019, 6:50 AM
Can you give a motivating use-case, please. Preferably some piece of real Kotlin code you wrote that would become easier to read and to understand with pattern matching?
l

Leon K

12/06/2019, 4:23 PM
i guess the main usage would be for working with sealed classes. I love them and i use them a LOT, but the current way of reaching into the values of a result by relying on the smart-cast makes it a bit ugly.
Copy code
val myValue = when(sealedResult) {
  is MyResult.Ok -> sealedResult.value
  is MyResult.Err -> sealedResult.errorValue
}
is still okay, (but a bit anoyying), but as soon as you need to reach into more nested structures or need to match on multiple sealed classes, this becomes hard to write and read. imagine the following:
Copy code
val myValue = match(loggingConfig, IntesomeWebResult) {
  _, WebResult.Ok(myData) -> ...
  _, WebResult.Loading -> ...
  LoggingConfig.Ignore, _  -> {}
  LoggingConfig.WriteOnlyFatal(logFile), WebResult.Err(Error.Fatal(msg)) -> logFile.appendLog(msg)
  LoggingConfig.WriteAll(logFile), WebResult.Err(error) -> logFile.appendLog(error.msg)
  LoggingConfig.PrintLogs, WebResult.Err(error) -> println(error.msg)
}
i know, this is a pretty bad example (i'm rather uncreative atm), but it does show a neat usecase for pattern-matching in complex situations. it makes it easy to see under which circumstances things are ignored or used, without having to look at long property-access-chains or complex, nested if statements
👍 1
r

raulraja

12/08/2019, 10:46 PM
If it helps you in any way Arrow Meta optics plugin will project optics over companions automatically or any object you tell it to that you will be able to use to pattern match but it will not look like destructuring in Scala as in the example above it would be something along the lines of
Copy code
when (result) {
  WebResult.ok.data -> ...
}
You can already do this kind of pattern matching with prisms and lenses in arrow today <https//arrow kt.io/docs/optics/dsl/|https//arrow-kt.io/docs/optics/dsl/>
👍 1
If you use optics you don't need to pattern match because you can focus and manipulate any deeply nested structure you care about directly without asking questions or destructuring elements manually
This works the same for all data structures even recursive ones
d

damian

01/01/2020, 1:09 AM
I am probably late to the party, but in regard to Roman's question - Jake had a pretty compelling example in his KotlinConf 2019 talk (40:44):

https://youtu.be/te3OU9fxC8U?t=2444

1
t

tmg

01/03/2020, 10:16 AM
I didn't know about that upcoming feature! thanks @damian
2 Views