http://www.artima.com/weblogs/viewpost.jsp?thread=281160
Sean
On Feb 4, 3:08 pm, Sean Devlin <francoisdev...@gmail.com> wrote:
> Do we have a concise way of doing this? Is it actually useful?
> http://www.artima.com/weblogs/viewpost.jsp?thread=281160
Yep, see clojure.contrib.types/match.
I recently used it in an almost frivolous way in this thread, because
I thought it was pretty and intensely readable:
http://groups.google.com/group/comp.lang.lisp/msg/80cfc28feaf4a1e9
I can't say I haven't used pattern matching as much as I probably
should, unless we count destructuring, regexes and an Eliza-like thing
I once wrote as part of an NLP project. Haskellers seem to use it a
lot, I get the impression.
All the best,
Tayssir
Are you talking about the pattern matching or the "for" loop?
--
Dr Jon Harrop, Flying Frog Consultancy Ltd.
http://www.ffconsultancy.com/?e
Excuse me, I mean that I haven't used it much though I keep hearing
about it...
Ok. Pattern matching is a core construct from the ML family of languages and,
consequently, is now ubiquitous in F#, OCaml, Standard ML and Haskell as well
as Scala. In the MLs, pattern matching is the only way to destructure data.
For example, you can extract the two elements of a pair and bind their values
to the variable names "a" and "b" as follows (OCaml/F# code):
let a, b = a_pair
Pattern matching is a powerful technique that has been generalized in many
ways, so you can also destructure a pair of pairs by nesting patterns:
let (x0, y0), (x1, y1) = two_vectors
Pattern matching is also used for dispatch in those languages (although the
object oriented ones including OCaml and F# also provide method dispatch).
Moreover, patterns can match on more than just objects, e.g. numbers:
let rec factorial = function
| 0 | 1 -> 1
| n -> n * factorial(n-1)
Note the "or-pattern" 0|1 to match either 0 or 1.
A more advanced example including nesting, or-patterns, guarded patterns
(with "when") and named subpatterns is to merge two sorted lists (OCaml/F#
code):
let rec merge = function
| [], xs | xs, [] -> xs
| x::xs', (y::_ as ys) when x <= y -> x::merge(xs', ys)
| xs, y::ys' -> y::merge(xs, ys')
I've written about it here:
http://www.ffconsultancy.com/ocaml/benefits/pattern_matching.html
You may also be interested in this symbolic simplifier challenge:
http://www.lambdassociates.org/studies/study10.htm
Note that the Common Lisp solutions are 50-160% longer and 1.7-7.5x slower
than the OCaml.
Pattern matching is uncommon is Lisps because its core benefits (static
checking and performance) rely upon static type information. However, some
dynamic languages (e.g. Mathematica) do provide and make heavy use of pattern
matching. On the other hand, dynamic languages can do lots of funky things
with pattern matching that static languages do not, most notably allowing
patterns to be generated at run-time (even MetaOCaml does not allow this).
A major disadvantage of pattern matching can be that it requires libraries to
expose their internals in order for a user to be able to pattern match over
them. This problem was solved using view patterns which are bundled with F#
(as "active patterns") and Scala (as "extractors").
I have found pattern matching to be extremely valuable not only because it
permits very clear and concise solutions to many problems but also because
the static checking it provides allows me to leverage a static type system to
prove aspects of correctness that remove major classes of bugs from real
applications.
HTH.
He has a nice version that can be used for both Lisp-y and Haskell-y
stuff, though it's not quite as full featured as what you'd see in
traditional AI systems.
Tom
Thanks for a very intersting response.
Do you have any real experience in F#? I am really interested in
hearing your opinion/thoughts on it relative to other functional
languages (you appear to be quite well versed). It looks very
interesting, but I am frankly having a hard enough time with Clojure
to spend my time on trying to add more to my plate.
Thanks
Bassel
Yes. I consulted for Microsoft on F# twice, wrote both the first and the most
recent books on F#, wrote and published the world's first and second
commercial applications written in F# and am an editor and author for the
F#.NET Journal.
> I am really interested in
> hearing your opinion/thoughts on it relative to other functional
> languages (you appear to be quite well versed).
The main thing that sets F# apart from the other functional languages is that
it is officially backed by a huge corporation: Microsoft. They have put a lot
of time and money into F# (almost 10 years in the making and ~10 people on
the F# team now) and it really shows. F# is comparatively polished with a
nice IDE compared to other functional languages, although it still lacks
support for some features that C# has like GUI designer integration and WSDL.
F# is really bred for interactive technical computing. They took the core of
the OCaml language, which was known for being pragmatic and predictably
efficient, and made it a lot faster and added the good features from other
languages like Python and Haskell as well as new features like parallelism.
F# has first-class interop with the whole of .NET and, in particular, because
it is statically typed can easily be used to write components for C# users to
consume.
> It looks very
> interesting, but I am frankly having a hard enough time with Clojure
> to spend my time on trying to add more to my plate.
In the language zoo, F# and Clojure are very different (think C# vs Jython).
However, Clojure is similar in an unusual methodological way from the point
of view of functional programming: it is designed from the ground up to be
pragmatic. Most functional languages (e.g. OCaml, Haskell, Scala) are
designed by researchers for the purposes of generating papers and grant
funding. Consequently, they usually either have no support or poor support
for mundane but essential features like interoperability and they do not
absorb good features from elsewhere (because it would not constitute
research). In contrast, Clojure and F# are designed and implemented by real
world programmers for real world programmers and are not afraid to borrow
good features from other languages.
From a business point of view, this pragmatism means a healthier and wealthier
market of users who depend upon the language. That is reflected in the
funding (the Industrial Haskell Group failed to garner a single new
subscriber since its inception, the CAML Consortium garnered a dozen or so
users over several years but could not even fund a single developer whereas
Rich Hickey just had to ask his community to get complete funding and Steve
Ballmer is throwing resources at Microsoft).
Having tried both the academic and the pragmatic languages, I must say that I
really prefer not only the pragmatic tools but also the kinds of people who
gravitate around them. I much prefer reading about real users and their
experiences trying to apply technology to solve important problems, rather
than reading endless articles about scalably parallelized Fibonacci functions
and rigged language comparisons.