Ambrose and I have been working on a high performance pattern matching library for Clojure. There's much left to do but it's already in a place where it's fun to play around with and we think some of you might even find it useful even in this early form.
Some highlights:
* Literal patterns * Seq patterns with rest support * Map patterns, can constrain keys with only * Bindings can be introduced anywhere a wildcard might appear * No type constraints on columns * Lazy pattern matching semantics a la Haskell
This library implements Maranget's fascinating description for compiling pattern matching into good decision trees. Suffice to say, this library is pretty darn fast.
We look forward to hearing your feedback. For code, more documentation, and where we are heading you can look here:
On Mon, Aug 8, 2011 at 11:49 PM, David Nolen <dnolen.li...@gmail.com> wrote: > Ambrose and I have been working on a high performance pattern matching > library for Clojure. There's much left to do but it's already in a place > where it's fun to play around with and we think some of you might even find > it useful even in this early form.
> Some highlights:
> * Literal patterns > * Seq patterns with rest support > * Map patterns, can constrain keys with only > * Bindings can be introduced anywhere a wildcard might appear > * No type constraints on columns > * Lazy pattern matching semantics a la Haskell
> This library implements Maranget's fascinating description for compiling > pattern matching into good decision trees. Suffice to say, this library is > pretty darn fast.
> We look forward to hearing your feedback. For code, more documentation, and > where we are heading you can look here:
> -- > You received this message because you are subscribed to the Google > Groups "Clojure" group. > To post to this group, send email to clojure@googlegroups.com > Note that posts from new members are moderated - please be patient with > your first post. > To unsubscribe from this group, send email to > clojure+unsubscribe@googlegroups.com > For more options, visit this group at > http://groups.google.com/group/clojure?hl=en
> On Mon, Aug 8, 2011 at 11:49 PM, David Nolen <dnolen.li...@gmail.com> wrote:
>> Ambrose and I have been working on a high performance pattern matching >> library for Clojure. There's much left to do but it's already in a place >> where it's fun to play around with and we think some of you might even find >> it useful even in this early form.
>> Some highlights:
>> * Literal patterns >> * Seq patterns with rest support >> * Map patterns, can constrain keys with only >> * Bindings can be introduced anywhere a wildcard might appear >> * No type constraints on columns >> * Lazy pattern matching semantics a la Haskell
>> This library implements Maranget's fascinating description for compiling >> pattern matching into good decision trees. Suffice to say, this library is >> pretty darn fast.
>> We look forward to hearing your feedback. For code, more documentation, and >> where we are heading you can look here:
>> -- >> You received this message because you are subscribed to the Google >> Groups "Clojure" group. >> To post to this group, send email to clojure@googlegroups.com >> Note that posts from new members are moderated - please be patient with >> your first post. >> To unsubscribe from this group, send email to >> clojure+unsubscribe@googlegroups.com >> For more options, visit this group at >> http://groups.google.com/group/clojure?hl=en
> -- > You received this message because you are subscribed to the Google > Groups "Clojure" group. > To post to this group, send email to clojure@googlegroups.com > Note that posts from new members are moderated - please be patient with your first post. > To unsubscribe from this group, send email to > clojure+unsubscribe@googlegroups.com > For more options, visit this group at > http://groups.google.com/group/clojure?hl=en
> Ambrose and I have been working on a high performance pattern matching
> library for Clojure. There's much left to do but it's already in a place
> where it's fun to play around with and we think some of you might even find
> it useful even in this early form.
> Some highlights:
> * Literal patterns
> * Seq patterns with rest support
> * Map patterns, can constrain keys with only
> * Bindings can be introduced anywhere a wildcard might appear
> * No type constraints on columns
> * Lazy pattern matching semantics a la Haskell
> This library implements Maranget's fascinating description for compiling
> pattern matching into good decision trees. Suffice to say, this library is
> pretty darn fast.
> We look forward to hearing your feedback. For code, more documentation, and
> where we are heading you can look here:
Do you happen to have any simple descriptions/examples of where and how we might use this stuff in our daily programming repertoires? I for one am sure I'm not educated enough as to the value and utility of pattern matching - at the moment I just think "that looks cool" rather than "I'm definitely going to use that to do X and Y".
> Ambrose and I have been working on a high performance pattern matching library for Clojure. There's much left to do but it's already in a place where it's fun to play around with and we think some of you might even find it useful even in this early form.
> Some highlights:
> * Literal patterns > * Seq patterns with rest support > * Map patterns, can constrain keys with only > * Bindings can be introduced anywhere a wildcard might appear > * No type constraints on columns > * Lazy pattern matching semantics a la Haskell
> This library implements Maranget's fascinating description for compiling pattern matching into good decision trees. Suffice to say, this library is pretty darn fast.
> We look forward to hearing your feedback. For code, more documentation, and where we are heading you can look here:
> -- > You received this message because you are subscribed to the Google > Groups "Clojure" group. > To post to this group, send email to clojure@googlegroups.com > Note that posts from new members are moderated - please be patient with your first post. > To unsubscribe from this group, send email to > clojure+unsubscribe@googlegroups.com > For more options, visit this group at > http://groups.google.com/group/clojure?hl=en
> Do you happen to have any simple descriptions/examples of where and how we might use this stuff in our daily programming repertoires? I for one am sure I'm not educated enough as to the value and utility of pattern matching - at the moment I just think "that looks cool" rather than "I'm definitely going to use that to do X and Y".
To me pattern matching is the bee's knees :) If you have a lot of functions where you check the input for some certain type of value and then perform some action depending on the value(s), then pattern matching can be very useful. It's used extensively in Erlang and Haskell among others.
For example, say you have a function `decide` -
(defn decide "A very simple example using cond" [x y] (cond (= x :foo) (do-foo y) (= x :bar) (do-bar y) :else (do-default y)))
I expect two arguments x & y and depending on the value of `x`, I would like to call the functions `do-foo`, `do-bar` or `do-default` with the value of `y`.
See how the code is riddled with the conditional checks and my business logic (the part I care the most about). Using pattern-matching, I can write the above code a bit more succinctly like this -
(defn decide "A very simple example using match" [x y] (match [x y] [:foo arg] (do-foo arg) [:bar arg] (do-bar arg) [_ arg] (do-default arg)))
The above code is *much* clearer and conveys the exact logic that I am trying to implement. Internally `match` will rewrite the above to an optimised bit of code which uses `cond`.
If I am feeling adventurous, I can write a simple macro which will let me define the same function in an even more succinct manner like this -
(defm decide "A very simple example" ([:foo arg] (do-foo arg)) ([:bar arg] (do-bar arg)) ([_ arg] (do-default arg)))
A sample implementation of the `defm` macro used above could be something like this (UNTESTED!) -
It's even more awesome when you bring in complex maps, etc. into the picture.
I personally believe that David and Ambrose are doing some incredible work with match & core.logic; these two projects will prove be extremely useful in the future.
>> Do you happen to have any simple descriptions/examples of where and >> how we might use this stuff in our daily programming repertoires? I >> for one am sure I'm not educated enough as to the value and utility >> of pattern matching - at the moment I just think "that looks cool" >> rather than "I'm definitely going to use that to do X and Y".
> To me pattern matching is the bee's knees :) If you have a lot of > functions where you check the input for some certain type of value > and then perform some action depending on the value(s), then pattern > matching can be very useful. It's used extensively in Erlang and > Haskell among others.
> For example, say you have a function `decide` -
> (defn decide "A very simple example using cond" [x y] (cond (= x > :foo) (do-foo y) (= x :bar) (do-bar y) :else (do-default y)))
> I expect two arguments x & y and depending on the value of `x`, I > would like to call the functions `do-foo`, `do-bar` or `do-default` > with the value of `y`.
> See how the code is riddled with the conditional checks and my > business logic (the part I care the most about). Using > pattern-matching, I can write the above code a bit more succinctly > like this -
> (defn decide "A very simple example using match" [x y] (match [x y] > [:foo arg] (do-foo arg) [:bar arg] (do-bar arg) [_ arg] (do-default > arg)))
> The above code is *much* clearer and conveys the exact logic that I > am trying to implement. Internally `match` will rewrite the above to > an optimised bit of code which uses `cond`.
> If I am feeling adventurous, I can write a simple macro which will > let me define the same function in an even more succinct manner like > this -
> (defm decide "A very simple example" ([:foo arg] (do-foo arg)) ([:bar > arg] (do-bar arg)) ([_ arg] (do-default arg)))
> A sample implementation of the `defm` macro used above could be > something like this (UNTESTED!) -
> It's even more awesome when you bring in complex maps, etc. into the > picture.
> I personally believe that David and Ambrose are doing some > incredible work with match & core.logic; these two projects will > prove be extremely useful in the future.
On Tue, Aug 9, 2011 at 5:43 PM, Baishampayan Ghose <b.gh...@gmail.com>wrote:
> A sample implementation of the `defm` macro used above could be > something like this (UNTESTED!) - > *snip*
`defm` is already at `match.core/defmatch`. Pretty neat :)
> I personally believe that David and Ambrose are doing some incredible > work with match & core.logic; these two projects will prove be > extremely useful in the future.
David thinks up some amazing projects! Thanks for the encouragement, it's really way too much fun!
1, nil]], ;; results in 0 [x y]] ;; the variables to match
2. The pattern matrix is "compiled" into a decision tree, a DAG. Switch nodes can take multiple routes down the tree, depending on which ":case" matches the ":occurance".
On Tue, Aug 9, 2011 at 3:50 AM, Sam Aaron <samaa...@gmail.com> wrote: > Exciting stuff!
> Do you happen to have any simple descriptions/examples of where and how we > might use this stuff in our daily programming repertoires? I for one am sure > I'm not educated enough as to the value and utility of pattern matching - at > the moment I just think "that looks cool" rather than "I'm definitely going > to use that to do X and Y".
Also we've reserved vector notation for data structures that support random access and slicing. For example say you're doing some network programming:
(match [byte-buffer] ([127 1 38 58 l & rest] ...) ([127 2 0 0 l & rest] ...) ([1 id 0 0 l & rest] ...))
This should of course expand out to highly optimized calls to pull apart the particular data structure. Because of lazy pattern matching it would be efficient without you would having to write such logic by hand (it will automatically check ahead on bytes that actually matter for determining which branch to take).
On Tue, Aug 9, 2011 at 6:34 AM, Ambrose Bonnaire-Sergeant <
abonnaireserge...@gmail.com> wrote: > For those browsing the source, I'll give a quick run through of what's > going on.
This means that the machinery is already exposed. There's a bit of code cleanup to do but the pattern matcher is meant to be *extensible*. So if you spend some time to understand how the library works you can extend the pattern matcher to deal with new kind of patterns. For example you may very well decide that you'd like to do the following:
We may or may not add regex support to match, but it doesn't mean that you shouldn't be able to. It will take some time to figure out what the precise protocol is for this, but we're thinking about it as we implement the current feature set.
On Tue, Aug 9, 2011 at 1:49 AM, David Nolen <dnolen.li...@gmail.com> wrote: > Ambrose and I have been working on a high performance pattern matching > library for Clojure. There's much left to do but it's already in a place > where it's fun to play around with and we think some of you might even find > it useful even in this early form.
> Some highlights:
> * Literal patterns > * Seq patterns with rest support > * Map patterns, can constrain keys with only > * Bindings can be introduced anywhere a wildcard might appear > * No type constraints on columns > * Lazy pattern matching semantics a la Haskell
> This library implements Maranget's fascinating description for compiling > pattern matching into good decision trees. Suffice to say, this library is > pretty darn fast.
> We look forward to hearing your feedback. For code, more documentation, and > where we are heading you can look here:
A quick heads up. We've switched to vectors for seq matching. This brings things in line with Clojure destructuring syntax, but more importantly it frees us to reserve lists for custom syntax. This will allow for things like this:
(match [x y] [({1 :b} :as m) _] ...)
We'll probably support optimized vector matching like so:
This is great stuff: thank you! I can totally see this being the kind
of thing like destructuring, where once you've used it you won't want
to go back :)
Just to clarify, you can extend the matching to new types but the match is 'closed' in the sense that unlike mutimethods you can't add additional cases? Is that correct?
On Wed, Aug 10, 2011 at 5:43 PM, James Sofra <james.so...@gmail.com> wrote:
> Just to clarify, you can extend the matching to new types but the match is > 'closed' in the sense that unlike mutimethods you can't add additional > cases? Is that correct?
For the 0.1 release, that is correct.
In future releases, we will explore 'open' matching, a la multimethods.