Pattern-matching means that the branching primitive not only dispatches to different code based on an input tag, but also that it places different values of different types in scope according to the branch.
Most languages only branch on booleans, without gaining any type information at all. This is actually a big problem and relates to the nullability problem, explained at: http://existentialtype.wordpress.com/2011/03/15/boolean-blin...
For example, in C:
switch(ptr) {
case NULL: ... handle null case ...
default: ... use ptr as if it weren't NULL ...
}
This is unsafe -- because nothing prevents you from using ptr in the "NULL" case, and the compiler does not give you anything in the non-NULL case.In Haskell:
case ptr of
Nothing -> ... can't use ptr as a value here,
it's wrapped with Maybe ...
Just x -> ... pattern-matching gave us "x" of
the correct type.
We can now safely use it.In the presence of static typing, "emulating" pattern matching defeats the purpose, because the purpose of pattern matching is removing boolean blindness. With the "emulated" code you still get runtime-failing boolean-blind code.
By the way, pattern-matching is indeed very much related to sum types (part of "Algebraic data types"), which C lacks. To have pattern matching in a statically typed language, you would need to have sum types as well.
reverse [] = []
reverse (x:xs) = reverse xs ++ [x]
being sugar for reverse list = case list of
[] -> []
(x:xs) -> reverse xs ++ [x]
Since in that case, pattern matching on arguments is really just sugar for a case statement.He said pattern-matching was sugar for "case/switch construct present in many, many languages". That implies pattern-matching adds only syntax to the game, and that it doesn't add any useful things beyond the "switch" you find in C or Java, for example.