Pattern matching on its way to C#

by DotNetNerd 3. February 2015 16:47

csharp As the design notes for C# 7 reveals, Microsoft are thinking about introducing pattern matching into C# in version 7. I was really happy when I first heard this, because pattern matching is one of the things I often miss from F#, where I wrote about the joy of pattern matching way back in the beginning of 2008. It doesn't get much more nice and succinct than this.

match value with
| "a" -> printfn "The value was an a"
| "b" -> printfn "The value was a b"
| _ -> printfn "Unknown value"

C# pattern matching syntax proposal

It is very very early days, so nothing has been decided with reguard to the syntax, but initial thoughts seem to revolve around extending the switch statement. With slight modifications to resemble the above pattern match I arrive at the following.

switch (value) {
case "a":
    Console.WriteLine("The value was an a");
case "b":
    Console.WriteLine("The value was a b");
    Console.WriteLine("Unknown value");

Looking at other languages

This makes me think about how pattern matching looks on the surface languages like Elixir

case value do
    "a" ->
        IO.puts "The value was an a"
    "b" ->
        IO.puts "The value was a b"
    _ ->
        IO.puts "Unknown value"

and even more in Scala

value match{
   case "a" => println("The value was an a")
   case "b" => println("The value was a b")
   case _ => println("Unknown value")

My pet peeve with switch statements

As much as I love the idea of pattern matching in C# I do have a pet peeve that gets trampled with the current proposal. I really dislike the need for break statements in every case statement for the general case (no pun intended) for switch statements in C#. This is already the case today, but with the proposal it will be even more visible.

It has actually been quite a while since I wrote a switch statement, because I pretty much always go from if statements to implementing something like a chain of responsibilty as complexity grows, simply to get around them. It is a decision that I also make with some regret though, because it moves the logic into a number of classes, and has a readability cost along with smelling like premature optimization.

Sure the proposal shows the option of using if statements when pattern matching, but with any real complexity this also smells and is not very succinct.  So all though I don't have the golden solution up my sleeve, I do hope they come up with a better syntax. Should I make a suggestion then one obvious way of going about it would be to look at the Scala syntax and express the handlers as delegates, so they could be implemented as either anonymous delegates or lambdas. With that we would arrive at the following.

switch (value) {
    case "a" => Console.WriteLine("The value was an a")
    case "b" => Console.WriteLine("The value was a b")
    default => Console.WriteLine("Unknown value")

IMHO this is much nicer, less error prone and more succinct.

And finally where are my active patterns?

To drive it all the way home and make pattern matching closer to what we can do in F#, I would also like to have active patterns. Active patterns provide a nice way of extending the language and building your own internal DSL, so your pattern matches remain succinct, all while you get to reuse the logic associated with doing the matching.

Who am I?

My name is Christian Holm Diget, and I work as an independent consultant, in Denmark, where I write code, give advice on architecture and help with training. On the side I get to do a bit of speaking and help with miscellaneous community events.

Some of my primary focus areas are code quality, programming languages and using new technologies to provide value.

Microsoft Certified Professional Developer

Microsoft Most Valuable Professional

Month List