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");
break;
case "b":
Console.WriteLine("The value was a b");
break;
default:
Console.WriteLine("Unknown value");
break
}
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"
end
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.