Why I love pattern matching:
- Pattern matching makes it very easy to write recursive programs. For example, for terminating the recursion, traditionally you'd have to wrap your terminating condition (for example, (equal list1 nil)) in a cond or if, and manually test it during every recursive call. That's something you'd hate doing if you've ever written programs in Erlang or Haskell.
- I frequently write programs that progressively destructure lists, and having to pull out the car of a car of a car, can be a pain sometimes. With pattern matching, I can have these pulled out and bound to variables - automatically.
Unfortunately, Common Lisp doesn't have such a notion built into it (some people talk about Destructuring bind. Please, it works only for macro parameters, not functions. and is very limited in what it can do (in this context)).
To see just how nice pattern matching is and why it would suck if your language didn't or couldn't have it, consider the classical factorial example in Common Lisp and its erlang equivalent:
Common Lisp:
Erlang:
(defun fact(n)
(cond ((equal n 0) 1)
((> n 0) (* n
(fact (- n 1))))))
Erlang clearly wins, the code is much more readable and elegant than the common lisp version. Lisp with an evil grin, says, hold it right there! and pulls out a cool library from its arsenal called bpm. Its really cool in that its written entirely in Portable Common Lisp and is yet another example of how powerful lisp can be in extending itself. With bpm, you can now define your lisp functions with arguments that pattern match and bind to variables.. just like how you would in Erlang/Haskell.
fact(0) -> 1;
fact(N) -> N * fact(N - 1).
Some examples in Common Lisp to show you how clean your code will look:
Factorial:
Fibonacci of a number:
(def! fact (0) 1)
(def fact (_n) (* _n
(fact (- _n 1))))
It gets even better when you have to destructure lists recursively:
(def! fib (0) 0)
(def fib (1) 1)
(def fib (_n) (+ (fib (- _n 1))
(fib (- _n 2))))
A function that adds all the elements of a list:
Sweet! :)
(def! myf1 () 0)
(def myf1 (_head . _tail)
(+ _head (myf1 _tail)))