1. 14
  1.  

  2. 7

    I like the aesthetic of pattern matching and I agree that it can make things more readable, but this article presents a false dichotomy between either pattern matching with enum type safety, or procedural languages without it.

    In the event that branching on the language is rewritten as a switch statement, I was surprised to find that Microsoft’s C# compiler apparently does not have any flags to enable the desired warning (at least such that I was able to find with a cursory web search). However, this isn’t a fundamental limitation of procedural languages. Take the following C99 code and compile it in GCC:

    https://gist.github.com/318f6047ad167cf7cd15

    You’ll get the following error message if -Werror=switch is specified (which is implied if you compile with -Wall -Werror):

    % gcc-4.8 -Werror=switch -o switch switch.c
    switch.c: In function ‘convert’:
    switch.c:13:2: error: enumeration value ‘GERMAN’ not handled in switch [-Werror=switch]
      switch (lang) {
      ^
    cc1: some warnings being treated as errors
    
    1. 2

      I’ve recently started learning Rust and have also discovered the joys of pattern matching. It’s basically my go-to code structure now. Before attempting anything else, I’ll see if I can rearrange my code to fit into a match.

      Code looks cleaner and is very self-documenting. I often prefer verbosity to terseness when it comes to coding, but I find match structures to be both terse and very easy to read. It does exactly what it looks like it does. And the compiler guarantees I’m not making any stupid mistakes. Win-win in my book.

      1. 8

        I think pattern matching is very over-used. We should use a function whenever possible. For example, I hate seeing this all the time:

        def x(a: Option[Int]) = a match {
          case Some(i) => i + 1
          case None => 0
        }
        

        Use a function!

        def x(a: Option[Int]) = a.fold(0)(_ + 1)
        

        We can pass a.fold around as a function, but we can’t pass the pattern around. Functions can be abstracted over!

        1. 2

          At least in F# function keyword and Haskell, I believe pattern matching is done when you call the function, much like regular method overloading in C#. It is possible to pass those around as functions, unless I am missing something.

          Also, in your example, isn’t the def x a function that could be passed around?

          1. 3

            x is a function we can pass around but we should make functions just containing patterns to pass around, not mix patterns into our logic.

        2. 1

          I agree about the combination of terseness and ease of reading.

          The one thing I have been considering is how pattern matching is much more declarative, you say what you want to happen, not how to do it. I am still not certain what all the ramifications of that are, but it makes for simple code!