<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>brool &#187; pattern</title>
	<atom:link href="http://www.brool.com/index.php/tag/pattern/feed" rel="self" type="application/rss+xml" />
	<link>http://www.brool.com</link>
	<description>brool \brool\ (n.) : a low roar; a deep murmur or humming</description>
	<lastBuildDate>Fri, 20 Jan 2012 07:58:59 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3</generator>
		<item>
		<title>Pattern Matching In Clojure</title>
		<link>http://www.brool.com/index.php/pattern-matching-in-clojure</link>
		<comments>http://www.brool.com/index.php/pattern-matching-in-clojure#comments</comments>
		<pubDate>Wed, 12 Aug 2009 09:38:57 +0000</pubDate>
		<dc:creator>tim</dc:creator>
				<category><![CDATA[clojure]]></category>
		<category><![CDATA[coding]]></category>
		<category><![CDATA[haskell]]></category>
		<category><![CDATA[matching]]></category>
		<category><![CDATA[ocaml]]></category>
		<category><![CDATA[pattern]]></category>

		<guid isPermaLink="false">http://www.brool.com/?p=351</guid>
		<description><![CDATA[Updated: Note that this is available as a clojars module. Clojure code density seems to be pretty good. There are a fair number of convenient shortforms in the language; for example, associative datatypes all act as a function &#8212; so given a hash map you can reference it with (my-hashmap :key). The base language itself [...]]]></description>
			<content:encoded><![CDATA[<p><b>Updated</b>:  Note that this is available as a <a href="http://clojars.org/pattern-match">clojars module</a>.</p>

<p>Clojure code density seems to be pretty good. There are a fair number of convenient shortforms in the language; for example, associative datatypes all act as a function &mdash; so given a hash map you can reference it with (my-hashmap :key).  The base language itself is probably about as expressive as Python (or a bit better), but you have the added advantage of being able to use macros as needed to really get the code density up.</p>

<p>Nonetheless, I really wanted something like Ocaml&#8217;s / Haskell&#8217;s pattern matching; it makes some code wonderfully concise.</p>

<p>Accordingly, I hacked something up, based on Clojure&#8217;s built-in destructuring. Some examples:</p>

<p>Literal values match against the same value, while _ matches against any non-nil value (and nil matches against any nil one).  Additionally, :when clauses can be used for conditional checks.</p>


<div class="wp-geshi-highlight-wrap5"><div class="wp-geshi-highlight-wrap4"><div class="wp-geshi-highlight-wrap3"><div class="wp-geshi-highlight-wrap2"><div class="wp-geshi-highlight-wrap"><div class="wp-geshi-highlight"><div class="clojure"><pre class="de1"><span class="co1">; simple recursive evaluator</span>
<span class="br0">&#40;</span><span class="kw1">defn</span> arithmetic <span class="br0">&#91;</span>lst<span class="br0">&#93;</span>
  <span class="br0">&#40;</span>match lst
    v  :<span class="kw1">when</span> <span class="br0">&#40;</span>number? v<span class="br0">&#41;</span>  v
    <span class="br0">&#91;</span> _ <span class="st0">&quot;error&quot;</span> _<span class="br0">&#93;</span>     <span class="st0">&quot;error&quot;</span>
    <span class="br0">&#91;</span> _ _ <span class="st0">&quot;error&quot;</span><span class="br0">&#93;</span>     <span class="st0">&quot;error&quot;</span>
    <span class="br0">&#91;</span> <span class="st0">&quot;add&quot;</span> a b <span class="br0">&#93;</span>      <span class="br0">&#40;</span><span class="sy0">+</span> <span class="br0">&#40;</span>arithmetic a<span class="br0">&#41;</span> <span class="br0">&#40;</span>arithmetic b<span class="br0">&#41;</span><span class="br0">&#41;</span>
    <span class="br0">&#91;</span> <span class="st0">&quot;sub&quot;</span> a b <span class="br0">&#93;</span>      <span class="br0">&#40;</span><span class="sy0">-</span> <span class="br0">&#40;</span>arithmetic a<span class="br0">&#41;</span> <span class="br0">&#40;</span>arithmetic b<span class="br0">&#41;</span><span class="br0">&#41;</span>
    <span class="br0">&#91;</span> <span class="st0">&quot;mul&quot;</span> a b <span class="br0">&#93;</span>      <span class="br0">&#40;</span><span class="sy0">*</span> <span class="br0">&#40;</span>arithmetic a<span class="br0">&#41;</span> <span class="br0">&#40;</span>arithmetic b<span class="br0">&#41;</span><span class="br0">&#41;</span>
    <span class="br0">&#91;</span> <span class="st0">&quot;div&quot;</span> a b <span class="br0">&#93;</span>      <span class="br0">&#40;</span><span class="sy0">/</span> <span class="br0">&#40;</span>arithmetic a<span class="br0">&#41;</span> <span class="br0">&#40;</span>arithmetic b<span class="br0">&#41;</span><span class="br0">&#41;</span>
    <span class="br0">&#91;</span> <span class="st0">&quot;squared&quot;</span> a <span class="br0">&#93;</span>    <span class="br0">&#40;</span>arithmetic <span class="br0">&#91;</span><span class="st0">&quot;mul&quot;</span> <span class="br0">&#40;</span>arithmetic a<span class="br0">&#41;</span> <span class="br0">&#40;</span>arithmetic a<span class="br0">&#41;</span><span class="br0">&#93;</span><span class="br0">&#41;</span>
    _                  <span class="st0">&quot;error&quot;</span> <span class="br0">&#41;</span><span class="br0">&#41;</span></pre></div></div></div></div></div></div></div>




<p>Both collections and single values can be used:</p>


<div class="wp-geshi-highlight-wrap5"><div class="wp-geshi-highlight-wrap4"><div class="wp-geshi-highlight-wrap3"><div class="wp-geshi-highlight-wrap2"><div class="wp-geshi-highlight-wrap"><div class="wp-geshi-highlight"><div class="clojure"><pre class="de1"><span class="co1">;; return signum fr a number</span>
<span class="br0">&#40;</span><span class="kw1">defn</span> signum <span class="br0">&#91;</span>x<span class="br0">&#93;</span>
  <span class="br0">&#40;</span>match x 
     <span class="nu0">0</span> <span class="nu0">0</span>
     n :<span class="kw1">when</span> <span class="br0">&#40;</span><span class="sy0">&lt;</span> n <span class="nu0">0</span><span class="br0">&#41;</span> <span class="sy0">-</span><span class="nu0">1</span>
     _ <span class="nu0">1</span><span class="br0">&#41;</span><span class="br0">&#41;</span></pre></div></div></div></div></div></div></div>




<p>The pattern matching is stricter than the typical destructure;  whereas [ a b ] will destructure against a list of any number of elements, [ a b ] will pattern match only against a list of two elements.</p>


<div class="wp-geshi-highlight-wrap5"><div class="wp-geshi-highlight-wrap4"><div class="wp-geshi-highlight-wrap3"><div class="wp-geshi-highlight-wrap2"><div class="wp-geshi-highlight-wrap"><div class="wp-geshi-highlight"><div class="clojure"><pre class="de1"><span class="br0">&#40;</span>match x 
    <span class="br0">&#91;</span><span class="br0">&#93;</span>    <span class="st0">&quot;empty&quot;</span>
    <span class="br0">&#91;</span>_<span class="br0">&#93;</span>   <span class="st0">&quot;one element&quot;</span>
    <span class="br0">&#91;</span>a a<span class="br0">&#93;</span> <span class="st0">&quot;two identical elements&quot;</span>
    <span class="br0">&#91;</span>_ _<span class="br0">&#93;</span> <span class="st0">&quot;two elements&quot;</span>
    _     <span class="st0">&quot;three or more&quot;</span><span class="br0">&#41;</span></pre></div></div></div></div></div></div></div>




<p>If the same variable occurs in multiple locations in the parameter list, it will be checked for equality.  The &#038; tail form can be used to specify the rest of the list.</p>


<div class="wp-geshi-highlight-wrap5"><div class="wp-geshi-highlight-wrap4"><div class="wp-geshi-highlight-wrap3"><div class="wp-geshi-highlight-wrap2"><div class="wp-geshi-highlight-wrap"><div class="wp-geshi-highlight"><div class="clojure"><pre class="de1"><span class="co1">;; count identical elements in the same location in two lists:</span>
<span class="br0">&#40;</span><span class="kw1">defn</span> <span class="kw1">count</span><span class="sy0">=</span> <span class="br0">&#91;</span> lst1 lst2 <span class="br0">&#93;</span>
  <span class="br0">&#40;</span><span class="kw1">loop</span> <span class="br0">&#91;</span> a lst1 b lst2 <span class="kw1">count</span> <span class="nu0">0</span> <span class="br0">&#93;</span>
    <span class="br0">&#40;</span>match <span class="br0">&#91;</span>a b<span class="br0">&#93;</span>
      <span class="br0">&#91;</span><span class="br0">&#91;</span>e <span class="sy0">&amp;</span> at<span class="br0">&#93;</span> <span class="br0">&#91;</span>e <span class="sy0">&amp;</span> bt<span class="br0">&#93;</span><span class="br0">&#93;</span>  <span class="br0">&#40;</span><span class="kw1">recur</span> at bt <span class="br0">&#40;</span><span class="kw1">inc</span> <span class="kw1">count</span><span class="br0">&#41;</span><span class="br0">&#41;</span>
      <span class="br0">&#91;</span><span class="br0">&#91;</span>_ <span class="sy0">&amp;</span> at<span class="br0">&#93;</span> <span class="br0">&#91;</span>_ <span class="sy0">&amp;</span> bt<span class="br0">&#93;</span><span class="br0">&#93;</span>  <span class="br0">&#40;</span><span class="kw1">recur</span> at bt <span class="kw1">count</span><span class="br0">&#41;</span>
      _                    <span class="kw1">count</span><span class="br0">&#41;</span><span class="br0">&#41;</span><span class="br0">&#41;</span></pre></div></div></div></div></div></div></div>




<p>Note that this is slightly more flexible than Haskell / ML, in that a variable of the same name can be multiple places in the pattern.</p>

<h3>Defining</h3>

<p>You can use the defnp macro to define a function that is pattern matched; it defines a function that takes one argument and has an implicit match statement.  For example, the signum function can be written:</p>


<div class="wp-geshi-highlight-wrap5"><div class="wp-geshi-highlight-wrap4"><div class="wp-geshi-highlight-wrap3"><div class="wp-geshi-highlight-wrap2"><div class="wp-geshi-highlight-wrap"><div class="wp-geshi-highlight"><div class="clojure"><pre class="de1">    <span class="br0">&#40;</span>defnp signum
       <span class="nu0">0</span> <span class="nu0">0</span>
       n :<span class="kw1">when</span> <span class="br0">&#40;</span><span class="sy0">&lt;</span> n <span class="nu0">0</span><span class="br0">&#41;</span> <span class="sy0">-</span><span class="nu0">1</span>
       _ <span class="nu0">1</span><span class="br0">&#41;</span></pre></div></div></div></div></div></div></div>




<p>(Thanks to <a href="http://infolace.blogspot.com/">Tom Faulhaber</a> for suggesting this)</p>

<h3>Gotchas</h3>

<p>The Clojure destructuring will cause an exception if you try to destructure a collection type with a value.</p>


<div class="wp-geshi-highlight-wrap5"><div class="wp-geshi-highlight-wrap4"><div class="wp-geshi-highlight-wrap3"><div class="wp-geshi-highlight-wrap2"><div class="wp-geshi-highlight-wrap"><div class="wp-geshi-highlight"><div class="clojure"><pre class="de1"><span class="br0">&#40;</span><span class="kw1">let</span> <span class="br0">&#91;</span><span class="br0">&#91;</span>a b<span class="br0">&#93;</span> <span class="nu0">10</span><span class="br0">&#93;</span> a<span class="br0">&#41;</span>
java<span class="sy0">.</span>lang<span class="sy0">.</span>UnsupportedOperationException: <span class="me1">nth</span> <span class="kw1">not</span> supported on this type: <span class="me1">Integer</span> <span class="br0">&#40;</span>NO_SOURCE_FILE:<span class="nu0">0</span><span class="br0">&#41;</span></pre></div></div></div></div></div></div></div>




<p>&#8230; so be sure to check such cases early in your match statement, if they are possible.</p>

<h3>How It Works</h3>

<p>The pattern matcher uses the built-in Clojure destructuring as the main mechanism, but adorns it so that the pattern can be verified.  For example, the code:


<div class="wp-geshi-highlight-wrap5"><div class="wp-geshi-highlight-wrap4"><div class="wp-geshi-highlight-wrap3"><div class="wp-geshi-highlight-wrap2"><div class="wp-geshi-highlight-wrap"><div class="wp-geshi-highlight"><div class="clojure"><pre class="de1"><span class="br0">&#40;</span>match x <span class="br0">&#91;</span>a a<span class="br0">&#93;</span> <span class="st0">&quot;two identical&quot;</span> <span class="br0">&#41;</span></pre></div></div></div></div></div></div></div>




turns into essentially the following:


<div class="wp-geshi-highlight-wrap5"><div class="wp-geshi-highlight-wrap4"><div class="wp-geshi-highlight-wrap3"><div class="wp-geshi-highlight-wrap2"><div class="wp-geshi-highlight-wrap"><div class="wp-geshi-highlight"><div class="clojure"><pre class="de1"><span class="br0">&#40;</span><span class="kw1">let</span> <span class="br0">&#91;</span> <span class="br0">&#91;</span> a g0001 <span class="sy0">&amp;</span> g0002 <span class="br0">&#93;</span> x <span class="br0">&#93;</span> 
     <span class="br0">&#40;</span><span class="kw1">if</span> <span class="br0">&#40;</span><span class="kw1">and</span> <span class="br0">&#40;</span><span class="kw1">not</span> <span class="br0">&#40;</span><span class="kw1">nil?</span> a<span class="br0">&#41;</span><span class="br0">&#41;</span> <span class="br0">&#40;</span><span class="sy0">=</span> g0001 a<span class="br0">&#41;</span> <span class="br0">&#40;</span><span class="kw1">nil?</span> g0002<span class="br0">&#41;</span><span class="br0">&#41;</span> <span class="st0">&quot;two identical&quot;</span> nil<span class="br0">&#41;</span><span class="br0">&#41;</span></pre></div></div></div></div></div></div></div>




<p>That is, the destructuring is done, but then the two variables are checked to make sure that they are equal, and the list is checked to make sure it is only two elements long.</p>

<h3>Source</h3>

<a href="http://github.com/brool/clojure-misc/tree">It&#8217;s all on Github</a>.]]></content:encoded>
			<wfw:commentRss>http://www.brool.com/index.php/pattern-matching-in-clojure/feed</wfw:commentRss>
		<slash:comments>13</slash:comments>
		</item>
	</channel>
</rss>

