Thread
#language-evolution
    l

    Leon K

    2 years ago
    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?
    sean

    sean

    2 years ago
    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.
    l

    Leon K

    2 years ago
    i do miss them as well. as i said, i dont think theyre planned, because they're deemed "to complex"
    sean

    sean

    2 years ago
    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

    2 years ago
    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
    elizarov

    elizarov

    2 years ago
    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

    2 years ago
    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.
    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:
    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
    raulraja

    raulraja

    2 years ago
    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
    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/>
    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
    damian

    damian

    2 years ago
    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

    t

    tmg

    2 years ago
    I didn't know about that upcoming feature! thanks @damian