Hacker News new | ask | show | jobs
by true_religion 3631 days ago
This is the starter code:

    publish :: Bool -> IO ()
    publish isDryRun =
      if isDryRun
        then do
          _ <- unsafePreparePackage dryRunOptions
          putStrLn "Dry run completed, no errors."
        else do
          pkg <- unsafePreparePackage defaultPublishOptions
          putStrLn (A.encode pkg)

This would be nicer if you could do multiple functions with pattern matching. In Elixir this would be:

    @spec publish(boolean) :: any
    def publish(true = _isDryRun) do
          _ = unsafePreparePackage dryRunOptions
          IO.puts "Dry run completed, no errors."
    end

    def publish(false = _isDryRun) do
          pkg = unsafePreparePackage defaultPublishOptions
          IO.puts (A.encode pkg)
    end

Pattern matching is pretty powerful, even going as far to give a dynamic, non-statically types language like Elixir the ability to 'destroy all iffs' too.
3 comments

You can do exactly the same kind of pattern matching in Haskell, but that's not at all the point of the article. It's equivalent to writing the conditional, it doesn't remove it.

    publish :: Bool -> IO ()
    publish True =
      unsafePreparePackage dryRunOptions >>
        putStrLn "Dry run completed, no errors."
    publish False = do
      pkg <- unsafePreparePackage defaultPublishOptions
      putStrLn (A.encode pkg)
Pattern matching is just as explicit as an if loop. In languages that implement it for null values, it is just as explicit as typing "if (foo == null)" in an imperative language. You have to think about it, and type just as much code to deal with it, as you would in a language without pattern matching.

The only upside to pattern matching that I can see is that you are forced by the compiler to match all possible inputs and check for nulls in some languages, which can help you avoid null pointer exceptions and such. But you haven't encapsulated anything, or saved yourself any thinking or typing, by using pattern matching. You've basically turned every function into a switch statement. It's vastly overrated.

Another advantage of pattern matching is extensibility.

Suppose you wish to add a new branch case. Under the traditional if/else (or switch) model, you'd need to modify the function containing the if statements. With pattern matching, you simply introduce a new function; it decentralizes the change and acts as a sort of simple, intuitive polymorphism.

The main advantage of pattern matching is that you can't forget it. If you forget to check for null, the customer complains that the program crashed. If you forget to handle the cases in a pattern, the compiler complains to you.
Or procedurally, you could just have two functions:

    publishLive
    publishDryRun
Which, of course, is not the point of the article either.