<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/atom10full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><feed xmlns="http://www.w3.org/2005/Atom">
 
  <title>marius a. eriksen</title>
  
  <link href="http://monkey.org/~marius" />
  <updated>2009-11-09T22:55:11-08:00</updated>
  <id>http://monkey.org/~marius</id>
  <author>
    <name>marius a. eriksen</name>
    <email>marius@monkey.org</email>
  </author>

  
  <link rel="self" href="http://feeds.feedburner.com/mariusaeriksen" type="application/atom+xml" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com" /><entry>
    <title>Haskell is beautiful in practice</title>
    <link href="http://monkey.org/~marius/haskell-is-beautiful-in-practice.html" />
    <updated>2009-11-05T00:00:00-08:00</updated>
    <id>http://monkey.org/~marius/./why-haskell-is-beautiful-in-practice</id>
    <content type="html">&lt;p&gt;I&amp;#8217;ve been writing a bit of &lt;a href='http://www.haskell.org'&gt;Haskell&lt;/a&gt; lately (see my &lt;a href='http://github.com/mariusaeriksen/'&gt;GitHub page&lt;/a&gt;), and it&amp;#8217;s an absolutely beautiful experience. And I mean that in every way: The language itself of course, but also the community, the documentation, the package system and the &lt;a href='http://hackage.haskell.org/platform/'&gt;Haskell platform&lt;/a&gt; ultimately help make the practice of writing Haskell more pleasing than any other I&amp;#8217;ve had any experience with.&lt;/p&gt;

&lt;p&gt;I find that Haskell lets me translate so many ideas and abstractions naturally and without the fuzz of too much indirection. My hope is to give you a small taste of what I&amp;#8217;m talking about. Please note that this is going to contain some deliberate (but mostly inconsequential) inaccuracies and I will also leave out details here and there. A lot of the code is also &amp;#8220;paraphrased&amp;#8221; to highlight the ideas behind it.&lt;/p&gt;

&lt;p&gt;I recently wrote an implementation of &lt;a href='http://bert-rpc.org'&gt;BERT&lt;/a&gt; in Haskell (&lt;a href='http://github.com/mariusaeriksen/bert/'&gt;github&lt;/a&gt;). I had the need for an RPC mechanism, and it seemed to fit my requirements rather well. &amp;#8220;BERTs&amp;#8221; are a subset of &lt;a href='http://www.erlang.org'&gt;Erlang&lt;/a&gt; terms, which are composable and have a straightforward external representation (albeit not as space efficient as something like Google&amp;#8217;s protocol buffers). So I figured this might be a good starting point for demonstrating some of the substantial ways in which Haskell provides facilities to create programs that are not only succinct but also readable and robust. At the same time, I hope to convince you that Haskell provides the kind of abstraction &amp;amp; encapsulation that is often much more natural than other approaches.&lt;/p&gt;

&lt;h2 id='types'&gt;Types&lt;/h2&gt;

&lt;p&gt;We need to be able to represent BERT terms in Haskell. Thus we introduce an algebraic type representing a Term (&lt;a href='http://github.com/mariusaeriksen/bert/blob/master/Data/BERT/Types.hs#L18'&gt;github&lt;/a&gt;).&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;span class='c1'&gt;-- | A single BERT term.&lt;/span&gt;
&lt;span class='kr'&gt;data&lt;/span&gt; &lt;span class='kt'&gt;Term&lt;/span&gt;
  &lt;span class='c1'&gt;-- Simple (erlang) terms:&lt;/span&gt;
  &lt;span class='ow'&gt;=&lt;/span&gt; &lt;span class='kt'&gt;IntTerm&lt;/span&gt;        &lt;span class='kt'&gt;Int&lt;/span&gt;
  &lt;span class='o'&gt;|&lt;/span&gt; &lt;span class='kt'&gt;FloatTerm&lt;/span&gt;      &lt;span class='kt'&gt;Float&lt;/span&gt;
  &lt;span class='o'&gt;|&lt;/span&gt; &lt;span class='kt'&gt;AtomTerm&lt;/span&gt;       &lt;span class='kt'&gt;String&lt;/span&gt;
  &lt;span class='o'&gt;|&lt;/span&gt; &lt;span class='kt'&gt;TupleTerm&lt;/span&gt;      &lt;span class='p'&gt;[&lt;/span&gt;&lt;span class='kt'&gt;Term&lt;/span&gt;&lt;span class='p'&gt;]&lt;/span&gt;
  &lt;span class='o'&gt;|&lt;/span&gt; &lt;span class='kt'&gt;BytelistTerm&lt;/span&gt;   &lt;span class='kt'&gt;ByteString&lt;/span&gt;
  &lt;span class='o'&gt;|&lt;/span&gt; &lt;span class='kt'&gt;ListTerm&lt;/span&gt;       &lt;span class='p'&gt;[&lt;/span&gt;&lt;span class='kt'&gt;Term&lt;/span&gt;&lt;span class='p'&gt;]&lt;/span&gt;
  &lt;span class='o'&gt;|&lt;/span&gt; &lt;span class='kt'&gt;BinaryTerm&lt;/span&gt;     &lt;span class='kt'&gt;ByteString&lt;/span&gt;
  &lt;span class='o'&gt;|&lt;/span&gt; &lt;span class='kt'&gt;BigintTerm&lt;/span&gt;     &lt;span class='kt'&gt;Integer&lt;/span&gt;
  &lt;span class='o'&gt;|&lt;/span&gt; &lt;span class='kt'&gt;BigbigintTerm&lt;/span&gt;  &lt;span class='kt'&gt;Integer&lt;/span&gt;
&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;This is pretty straightforward to read: a &lt;code&gt;Term&lt;/code&gt; can be either an &lt;code&gt;IntTerm&lt;/code&gt;, a &lt;code&gt;FloatTerm&lt;/code&gt; and so forth. The right column specifies the data for the type. The &lt;code&gt;IntTerm&lt;/code&gt; carries an integer, etc. An important detail here is that these are not different types: they are all type &lt;em&gt;constructors&lt;/em&gt; for the type &lt;code&gt;Term&lt;/code&gt;. That is, these are different ways to create a &lt;code&gt;Term&lt;/code&gt; type. Algebraic types may also be recursively defined. The &lt;code&gt;ListTerm&lt;/code&gt; constructor represents a list of other &lt;code&gt;Term&lt;/code&gt;s. Already with this simple declaration, we&amp;#8217;ve expressed most of the semantics of BERT terms. We can now express composite BERT terms. For example BERT defines dictionaries to be represented as &lt;code&gt;{bert, dict, [{key, value}]&lt;/code&gt;. In Haskell:&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;span class='kt'&gt;TupleTerm&lt;/span&gt; &lt;span class='p'&gt;[&lt;/span&gt; &lt;span class='kt'&gt;AtomTerm&lt;/span&gt; &lt;span class='s'&gt;&amp;quot;bert&amp;quot;&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='kt'&gt;AtomTerm&lt;/span&gt; &lt;span class='s'&gt;&amp;quot;dict&amp;quot;&lt;/span&gt;
          &lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='kt'&gt;ListTerm&lt;/span&gt; &lt;span class='p'&gt;[&lt;/span&gt;&lt;span class='kt'&gt;TupleTerm&lt;/span&gt; &lt;span class='p'&gt;[&lt;/span&gt;&lt;span class='kt'&gt;AtomTerm&lt;/span&gt; &lt;span class='s'&gt;&amp;quot;key&amp;quot;&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='kt'&gt;AtomTerm&lt;/span&gt; &lt;span class='s'&gt;&amp;quot;value&amp;quot;&lt;/span&gt;&lt;span class='p'&gt;]]]&lt;/span&gt;
&lt;/pre&gt;
&lt;/div&gt;
&lt;h2 id='typeclasses'&gt;Typeclasses&lt;/h2&gt;

&lt;p&gt;&lt;code&gt;Term&lt;/code&gt;s encapsulate the BERT type representation, and we will write code that can encode &lt;code&gt;Term&lt;/code&gt; values to a binary representation (as per the BERT spec). However, these values are not the most convenient to work with in other Haskell code. Furthermore, many &lt;code&gt;Term&lt;/code&gt;s have a natural &amp;#8220;more primitive&amp;#8221; Haskell type (eg. &lt;code&gt;IntTerm&lt;/code&gt; vs. &lt;code&gt;Int&lt;/code&gt;, &lt;code&gt;ListTerm&lt;/code&gt; vs. &lt;code&gt;[]&lt;/code&gt;).&lt;/p&gt;

&lt;p&gt;We would like to introduce &lt;code&gt;Term&lt;/code&gt;s from these types and vice-versa. The most primitive way to do this is via &lt;em&gt;pattern matching&lt;/em&gt; (this is ubiquitous in Haskell and other functional programming languages. Also see my &lt;a href='pattern-matching-in-python.html'&gt;poor attempt at implementing pattern matching in Python&lt;/a&gt;).&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;span class='nf'&gt;listify&lt;/span&gt; &lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='kt'&gt;ListTerm&lt;/span&gt; &lt;span class='n'&gt;l&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt;      &lt;span class='ow'&gt;=&lt;/span&gt; &lt;span class='n'&gt;listify&amp;#39;&lt;/span&gt; &lt;span class='n'&gt;l&lt;/span&gt;
&lt;span class='nf'&gt;listify&amp;#39;&lt;/span&gt; &lt;span class='kt'&gt;[]&lt;/span&gt;               &lt;span class='ow'&gt;=&lt;/span&gt; &lt;span class='kt'&gt;[]&lt;/span&gt;
&lt;span class='nf'&gt;listify&amp;#39;&lt;/span&gt; &lt;span class='p'&gt;((&lt;/span&gt;&lt;span class='kt'&gt;IntTerm&lt;/span&gt; &lt;span class='n'&gt;x&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt;&lt;span class='kt'&gt;:&lt;/span&gt;&lt;span class='n'&gt;xs&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt; &lt;span class='ow'&gt;=&lt;/span&gt; &lt;span class='n'&gt;x&lt;/span&gt;&lt;span class='kt'&gt;:&lt;/span&gt;&lt;span class='n'&gt;listify&amp;#39;&lt;/span&gt; &lt;span class='n'&gt;xs&lt;/span&gt;
&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;This code introduces a list of integers (&lt;code&gt;[Int]&lt;/code&gt;) from a &lt;code&gt;ListTerm&lt;/code&gt; containing &lt;code&gt;IntTerm&lt;/code&gt;s. Clearly going around creating little unpackers like this for everything is going to be quite cumbersome. Haskell provides a very nice solution. &lt;em&gt;Typeclasses&lt;/em&gt; let you declare &lt;em&gt;common traits&lt;/em&gt; to a set of types. For example, I can define a typeclass that declares the ability to translate a value of that a given type into or out of a &lt;code&gt;Term&lt;/code&gt; (&lt;a href='http://github.com/mariusaeriksen/bert/blob/master/Data/BERT/Term.hs#L116'&gt;github&lt;/a&gt;).&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;span class='kr'&gt;class&lt;/span&gt; &lt;span class='kt'&gt;BERT&lt;/span&gt; &lt;span class='n'&gt;a&lt;/span&gt; &lt;span class='kr'&gt;where&lt;/span&gt;
  &lt;span class='c1'&gt;-- | Introduce a &amp;#39;Term&amp;#39; from a Haskell value.&lt;/span&gt;
  &lt;span class='n'&gt;showBERT&lt;/span&gt; &lt;span class='ow'&gt;::&lt;/span&gt; &lt;span class='n'&gt;a&lt;/span&gt; &lt;span class='ow'&gt;-&amp;gt;&lt;/span&gt; &lt;span class='kt'&gt;Term&lt;/span&gt;
  &lt;span class='c1'&gt;-- | Introduce a Haskell value from a &amp;#39;Term&amp;#39;.&lt;/span&gt;
  &lt;span class='n'&gt;readBERT&lt;/span&gt; &lt;span class='ow'&gt;::&lt;/span&gt; &lt;span class='kt'&gt;Term&lt;/span&gt; &lt;span class='ow'&gt;-&amp;gt;&lt;/span&gt; &lt;span class='n'&gt;a&lt;/span&gt;
&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;This introduces two new functions. One to create a term from a Haskell value, and one to do the inverse. So what kinds of types can introduce Haskell values from BERT or vice-versa? A few are quite simple. The most trivial is for &lt;code&gt;Term&lt;/code&gt; itself.&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;span class='kr'&gt;instance&lt;/span&gt; &lt;span class='kt'&gt;BERT&lt;/span&gt; &lt;span class='kt'&gt;Term&lt;/span&gt; &lt;span class='kr'&gt;where&lt;/span&gt;
  &lt;span class='n'&gt;showBERT&lt;/span&gt; &lt;span class='ow'&gt;=&lt;/span&gt; &lt;span class='n'&gt;id&lt;/span&gt;
  &lt;span class='n'&gt;readBERT&lt;/span&gt; &lt;span class='ow'&gt;=&lt;/span&gt; &lt;span class='n'&gt;id&lt;/span&gt;
&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;To convert a &lt;code&gt;Term&lt;/code&gt; to a &lt;code&gt;Term&lt;/code&gt; is just the &lt;code&gt;id&lt;/code&gt;entity function. We need to cover a few more primitive Haskell types. The &lt;code&gt;BERT&lt;/code&gt; definition for lists is:&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;span class='kr'&gt;instance&lt;/span&gt; &lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='kt'&gt;BERT&lt;/span&gt; &lt;span class='n'&gt;a&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt; &lt;span class='ow'&gt;=&amp;gt;&lt;/span&gt; &lt;span class='kt'&gt;BERT&lt;/span&gt; &lt;span class='p'&gt;[&lt;/span&gt;&lt;span class='n'&gt;a&lt;/span&gt;&lt;span class='p'&gt;]&lt;/span&gt; &lt;span class='kr'&gt;where&lt;/span&gt;
  &lt;span class='n'&gt;showBERT&lt;/span&gt; &lt;span class='n'&gt;xs&lt;/span&gt;            &lt;span class='ow'&gt;=&lt;/span&gt; &lt;span class='kt'&gt;ListTerm&lt;/span&gt; &lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='n'&gt;map&lt;/span&gt; &lt;span class='n'&gt;showBERT&lt;/span&gt; &lt;span class='n'&gt;xs&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt;
  &lt;span class='n'&gt;readBERT&lt;/span&gt; &lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='kt'&gt;ListTerm&lt;/span&gt; &lt;span class='n'&gt;xs&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt; &lt;span class='ow'&gt;=&lt;/span&gt; &lt;span class='n'&gt;map&lt;/span&gt; &lt;span class='n'&gt;readBERT&lt;/span&gt; &lt;span class='n'&gt;xs&lt;/span&gt;
  &lt;span class='n'&gt;readBERT&lt;/span&gt; &lt;span class='kr'&gt;_&lt;/span&gt;             &lt;span class='ow'&gt;=&lt;/span&gt; &lt;span class='ne'&gt;error&lt;/span&gt; &lt;span class='s'&gt;&amp;quot;Invalid list type&amp;quot;&lt;/span&gt;
&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;Unlike Haskell lists, &lt;code&gt;BERT&lt;/code&gt; lists can be heterogeneous: they are lists of &lt;code&gt;Term&lt;/code&gt;s which, being an algebraic type, may eventually contain different types of data. Thus, to introduce a &lt;code&gt;BERT&lt;/code&gt; list, we return a &lt;code&gt;ListTerm&lt;/code&gt; that applies &lt;code&gt;showBERT&lt;/code&gt; to every element in the list. This also explains the typeclass restriction on &lt;code&gt;a&lt;/code&gt;: we require that the list we are encoding contains a type that also has a typeclass instance of &lt;code&gt;BERT&lt;/code&gt;. Similarly, to decode a list, we call &lt;code&gt;readBERT&lt;/code&gt; on each element, introducing a list with the decoded Haskell types. But what about the other way? Certainly we couldn&amp;#8217;t introduce a Haskell list from a heterogeneous BERT list. The code above looks deceiving in this way, but &lt;em&gt;type inference&lt;/em&gt; is going on in the background here. The type of &lt;code&gt;readBERT&lt;/code&gt; is &lt;code&gt;Term -&amp;gt; [a]&lt;/code&gt;. This inference is propagated when we pass &lt;code&gt;readBERT&lt;/code&gt; to &lt;code&gt;map&lt;/code&gt; as well; it&amp;#8217;s equivalent to the following code:&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;  &lt;span class='n'&gt;readBERT&lt;/span&gt; &lt;span class='ow'&gt;::&lt;/span&gt; &lt;span class='kt'&gt;Term&lt;/span&gt; &lt;span class='ow'&gt;-&amp;gt;&lt;/span&gt; &lt;span class='p'&gt;[&lt;/span&gt;&lt;span class='n'&gt;a&lt;/span&gt;&lt;span class='p'&gt;]&lt;/span&gt;
  &lt;span class='n'&gt;readBERT&lt;/span&gt; &lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='kt'&gt;ListTerm&lt;/span&gt; &lt;span class='n'&gt;xs&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt; &lt;span class='ow'&gt;=&lt;/span&gt; &lt;span class='n'&gt;map&lt;/span&gt; &lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='n'&gt;readBERT&lt;/span&gt; &lt;span class='ow'&gt;::&lt;/span&gt; &lt;span class='kt'&gt;Term&lt;/span&gt; &lt;span class='ow'&gt;-&amp;gt;&lt;/span&gt; &lt;span class='n'&gt;a&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt; &lt;span class='n'&gt;xs&lt;/span&gt;
&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;Note that you can also create your own typeclass instances that suits your needs. For example if your application keeps some internal representation of some well defined value, you could create a typeclass instance to convert this representation to and from &lt;code&gt;Term&lt;/code&gt;s.&lt;/p&gt;

&lt;h2 id='lazyness'&gt;Lazyness&lt;/h2&gt;

&lt;p&gt;The RPC specification for BERT provides a rather opaque notion of a transport. The transport, in essence, is a channel through which you can send and receive BERT terms. The terms are wrapped in a 4-byte header specifying its length.&lt;/p&gt;

&lt;p&gt;Haskell has a &lt;code&gt;Handle&lt;/code&gt; type that is an opaque representation of a file-like object. Sockets can also be fronted by handles. A popular module, &lt;code&gt;Data.ByteString&lt;/code&gt; provides a lazy bytestring type that can be backed by a handle. It&amp;#8217;s a type that looks like a bytestring, smells like a bytestring, and acts like a bytestring, except that when it needs more data, it requests it from the handle it&amp;#8217;s been constructed with. Similarly, our binary term decoder reads from such bytestrings, so it does not take much imagination to produce a list that represents the infinite stream of packets coming from the BERT peer (&lt;a href='http://github.com/mariusaeriksen/bert/blob/master/Data/BERT/Packet.hs#L46'&gt;github&lt;/a&gt;).&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;span class='nf'&gt;packets&lt;/span&gt; &lt;span class='ow'&gt;::&lt;/span&gt; &lt;span class='kt'&gt;ByteString&lt;/span&gt; &lt;span class='ow'&gt;-&amp;gt;&lt;/span&gt; &lt;span class='p'&gt;[&lt;/span&gt;&lt;span class='kt'&gt;Packet&lt;/span&gt;&lt;span class='p'&gt;]&lt;/span&gt;
&lt;span class='nf'&gt;packets&lt;/span&gt; &lt;span class='n'&gt;b&lt;/span&gt;
  &lt;span class='o'&gt;|&lt;/span&gt; &lt;span class='n'&gt;null&lt;/span&gt; &lt;span class='n'&gt;b&lt;/span&gt; &lt;span class='ow'&gt;=&lt;/span&gt; &lt;span class='kt'&gt;[]&lt;/span&gt;
  &lt;span class='o'&gt;|&lt;/span&gt; &lt;span class='n'&gt;otherwise&lt;/span&gt; &lt;span class='ow'&gt;=&lt;/span&gt; &lt;span class='n'&gt;p&lt;/span&gt;&lt;span class='kt'&gt;:&lt;/span&gt;&lt;span class='n'&gt;packets&lt;/span&gt; &lt;span class='n'&gt;b&amp;#39;&lt;/span&gt; 
  &lt;span class='kr'&gt;where&lt;/span&gt; &lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='n'&gt;p&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='n'&gt;b&amp;#39;&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt; &lt;span class='ow'&gt;=&lt;/span&gt; &lt;span class='n'&gt;parsePacket&lt;/span&gt; &lt;span class='n'&gt;b&lt;/span&gt;
&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;(In Haskell, &lt;code&gt;:&lt;/code&gt; is the list constructor: it prepends an item to a list, eg. &lt;code&gt;1:[2,3] == [1,2,3]&lt;/code&gt;.) &lt;code&gt;packets&lt;/code&gt; reads like a declaration: if our bytestring, &lt;code&gt;b&lt;/code&gt; is null, it is the empty list, otherwise, it is the first parsed packet from &lt;code&gt;b&lt;/code&gt;, plus the list of packets represented by the remainder of the string. This works in Haskell because everything is evaluated &lt;em&gt;lazily&lt;/em&gt;. This in effect means that, unless you specify otherwise, values are not computed (code is not evaluated) until needed. In practice, the Haskell runtime leaves a &amp;#8220;promise&amp;#8221; of a computation when the value is not needed immediately. The list constructor &lt;code&gt;:&lt;/code&gt; is no different: its arguments are not evaluated until needed. In our example this means that the list defined by &lt;code&gt;packets&lt;/code&gt; is lazily generated. So if we create such a value with &lt;code&gt;packet b&lt;/code&gt;, not until we examine the resulting list do we even begin parsing (or generating the list, or reading from the socket). This is an example by which we use lazyness to provide an &lt;em&gt;abstraction&lt;/em&gt;. It allows us to operate on the familiar list type while not being terribly concerned about how the list is being constructed. It also relieves us of having to create any further abstraction: we can translate our model of a transport almost perfectly into a primitive Haskell concept without having to go about creating unfamiliar interfaces.&lt;/p&gt;

&lt;h2 id='monadic_parsing'&gt;Monadic parsing&lt;/h2&gt;

&lt;p&gt;We created an algebraic type to represent terms, but their construction (if you need to work with the term type) can be a little cumbersome. Our representation&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;span class='kt'&gt;TupleTerm&lt;/span&gt; &lt;span class='p'&gt;[&lt;/span&gt; &lt;span class='kt'&gt;AtomTerm&lt;/span&gt; &lt;span class='s'&gt;&amp;quot;bert&amp;quot;&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='kt'&gt;AtomTerm&lt;/span&gt; &lt;span class='s'&gt;&amp;quot;dict&amp;quot;&lt;/span&gt;
          &lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='kt'&gt;ListTerm&lt;/span&gt; &lt;span class='p'&gt;[&lt;/span&gt;&lt;span class='kt'&gt;TupleTerm&lt;/span&gt; &lt;span class='p'&gt;[&lt;/span&gt;&lt;span class='kt'&gt;AtomTerm&lt;/span&gt; &lt;span class='s'&gt;&amp;quot;key&amp;quot;&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='kt'&gt;AtomTerm&lt;/span&gt; &lt;span class='s'&gt;&amp;quot;value&amp;quot;&lt;/span&gt;&lt;span class='p'&gt;]]]&lt;/span&gt;
&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;would be represented more succinctly in the erlang grammar as:&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;span class='p'&gt;{&lt;/span&gt;&lt;span class='n'&gt;bert&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='n'&gt;dict&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='p'&gt;[(&lt;/span&gt;&lt;span class='n'&gt;key&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='n'&gt;value&lt;/span&gt;&lt;span class='p'&gt;)]}&lt;/span&gt;
&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;If just writing code, you probably don&amp;#8217;t care too much about the difference: you typically don&amp;#8217;t make big static constructs, but rather create types programmatically anyway. However, with the BERT implementation I wanted to have a command line tool that allowed for testing &amp;amp; inspection of results. For example:&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;span class='nv'&gt;$ &lt;/span&gt;bert call localhost:8181 mod proc &lt;span class='s2'&gt;&amp;quot;{1, test, [5,6,7]}&amp;quot;&lt;/span&gt;
&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;Luckily, Haskell provides an excellent facility for parsing: &lt;a href='http://www.haskell.org/haskellwiki/Parsec'&gt;Parsec&lt;/a&gt;. Parsec uses monadic actions to simultaneously lex &amp;amp; parse its input. I won&amp;#8217;t go into monads here, but for our purposes here it is essentially a means by which you can run code in a certain context, and manipulate that context. It can provide a pure functional construct with which you can achieve the appearance of imperative programming. In the context of Parsec, its monad maintains the parser state (eg. where in the input are we, which rules have failed, which rules are yet to be tried, what is the output, etc.), and provides a set of functions that can operate within the context of the monad it provides. Here&amp;#8217;s our parser for a term.&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;span class='nf'&gt;p_term&lt;/span&gt; &lt;span class='ow'&gt;::&lt;/span&gt; &lt;span class='kt'&gt;Parser&lt;/span&gt; &lt;span class='kt'&gt;Term&lt;/span&gt;
&lt;span class='nf'&gt;p_term&lt;/span&gt; &lt;span class='ow'&gt;=&lt;/span&gt; &lt;span class='n'&gt;t&lt;/span&gt; &lt;span class='o'&gt;&amp;lt;*&lt;/span&gt; &lt;span class='n'&gt;spaces&lt;/span&gt;    
  &lt;span class='kr'&gt;where&lt;/span&gt; 
    &lt;span class='n'&gt;t&lt;/span&gt; &lt;span class='ow'&gt;=&lt;/span&gt;     &lt;span class='kt'&gt;IntTerm&lt;/span&gt;               &lt;span class='o'&gt;&amp;lt;$&amp;gt;&lt;/span&gt; &lt;span class='n'&gt;p_num&lt;/span&gt; &lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='n'&gt;readSigned&lt;/span&gt; &lt;span class='n'&gt;readDec&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt;
        &lt;span class='o'&gt;&amp;lt;|&amp;gt;&lt;/span&gt; &lt;span class='kt'&gt;FloatTerm&lt;/span&gt;             &lt;span class='o'&gt;&amp;lt;$&amp;gt;&lt;/span&gt; &lt;span class='n'&gt;p_num&lt;/span&gt; &lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='n'&gt;readSigned&lt;/span&gt; &lt;span class='n'&gt;readFloat&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt;
        &lt;span class='o'&gt;&amp;lt;|&amp;gt;&lt;/span&gt; &lt;span class='kt'&gt;AtomTerm&lt;/span&gt;              &lt;span class='o'&gt;&amp;lt;$&amp;gt;&lt;/span&gt; &lt;span class='n'&gt;p_atom&lt;/span&gt;
        &lt;span class='o'&gt;&amp;lt;|&amp;gt;&lt;/span&gt; &lt;span class='kt'&gt;TupleTerm&lt;/span&gt;             &lt;span class='o'&gt;&amp;lt;$&amp;gt;&lt;/span&gt; &lt;span class='n'&gt;p_tuple&lt;/span&gt;
        &lt;span class='o'&gt;&amp;lt;|&amp;gt;&lt;/span&gt; &lt;span class='kt'&gt;BytelistTerm&lt;/span&gt; &lt;span class='o'&gt;.&lt;/span&gt; &lt;span class='kt'&gt;C&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;pack&lt;/span&gt; &lt;span class='o'&gt;&amp;lt;$&amp;gt;&lt;/span&gt; &lt;span class='n'&gt;p_string&lt;/span&gt;
        &lt;span class='o'&gt;&amp;lt;|&amp;gt;&lt;/span&gt; &lt;span class='kt'&gt;ListTerm&lt;/span&gt;              &lt;span class='o'&gt;&amp;lt;$&amp;gt;&lt;/span&gt; &lt;span class='n'&gt;p_list&lt;/span&gt;
        &lt;span class='o'&gt;&amp;lt;|&amp;gt;&lt;/span&gt; &lt;span class='kt'&gt;BinaryTerm&lt;/span&gt;   &lt;span class='o'&gt;.&lt;/span&gt; &lt;span class='kt'&gt;B&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;pack&lt;/span&gt; &lt;span class='o'&gt;&amp;lt;$&amp;gt;&lt;/span&gt; &lt;span class='n'&gt;p_binary&lt;/span&gt;
&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;Again, reading very naturally: a term is &lt;code&gt;t&lt;/code&gt; possibly followed by some whitespace. (&lt;code&gt;a &amp;lt;* b&lt;/code&gt; means roughly &amp;#8220;run a, then b, but the value of the expression is the value of a&amp;#8221;). &lt;code&gt;t&lt;/code&gt; in turn can be either a &lt;code&gt;p_num&lt;/code&gt; wrapped with an &lt;code&gt;IntTerm&lt;/code&gt;, and so forth. (In this context, &lt;code&gt;&amp;lt;|&amp;gt;&lt;/code&gt; can very roughly be thought of as &amp;#8220;otherwise, try..&amp;#8221; and &lt;code&gt;&amp;lt;$&amp;gt;&lt;/code&gt; as &amp;#8220;wrap the results of the argument to the right with the thing on the left&amp;#8221;.)&lt;/p&gt;

&lt;p&gt;The various &lt;code&gt;p_*&lt;/code&gt;s are other parsers. For example the one for tuples is&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;span class='nf'&gt;p_tuple&lt;/span&gt; &lt;span class='ow'&gt;=&lt;/span&gt;
  &lt;span class='n'&gt;between&lt;/span&gt; &lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='n'&gt;char&lt;/span&gt; &lt;span class='sc'&gt;&amp;#39;{&amp;#39;&lt;/span&gt; &lt;span class='o'&gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class='n'&gt;spaces&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt; &lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='n'&gt;spaces&lt;/span&gt; &lt;span class='o'&gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class='n'&gt;char&lt;/span&gt; &lt;span class='sc'&gt;&amp;#39;}&amp;#39;&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt; &lt;span class='o'&gt;$&lt;/span&gt;
    &lt;span class='n'&gt;p_term&lt;/span&gt; &lt;span class='p'&gt;`&lt;/span&gt;&lt;span class='n'&gt;sepBy&lt;/span&gt;&lt;span class='p'&gt;`&lt;/span&gt; &lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='n'&gt;spaces&lt;/span&gt; &lt;span class='o'&gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class='n'&gt;char&lt;/span&gt; &lt;span class='sc'&gt;&amp;#39;,&amp;#39;&lt;/span&gt; &lt;span class='o'&gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class='n'&gt;spaces&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt;
&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;&lt;code&gt;between&lt;/code&gt; is one of the Parsec functions that means: between the parses of the following arguments, try to parse the third. The third argument states: &amp;#8220;try and parse a &lt;code&gt;p_term&lt;/code&gt; that is separated by maybe some whitespace, a comma and maybe some more whitespace.&amp;#8221;&lt;/p&gt;

&lt;h2 id='id1'&gt;&amp;#8230;&lt;/h2&gt;

&lt;p&gt;This is really just the tip of the ice berg. Most of my descriptions, especially those regarding the use of monads belie the rigor and generality of these constructs. If you&amp;#8217;d like to explore further, the &lt;a href='http://www.realworldhaskell.org/'&gt;Real World Haskell&lt;/a&gt; book is a great start point. The Haskell community is simply fantastic. Much conversation happens on &lt;a href='http://www.haskell.org/haskellwiki/IRC_channel'&gt;IRC&lt;/a&gt;, where there is typically an armada of people just waiting to discuss the finer points of this wonderful language with you.&lt;/p&gt;</content>
  </entry>
  
  <entry>
    <title>Pattern matching in Python</title>
    <link href="http://monkey.org/~marius/pattern-matching-in-python.html" />
    <updated>2009-05-11T00:00:00-07:00</updated>
    <id>http://monkey.org/~marius/./pattern-matching-in-python</id>
    <content type="html">&lt;p&gt;One of my favorite things about &lt;a href='http://www.erlang.org/'&gt;various&lt;/a&gt; &lt;a href='http://www.haskell.org/'&gt;functional&lt;/a&gt; &lt;a href='http://www.clojure.org/'&gt;programming&lt;/a&gt; &lt;a href='http://caml.inria.fr/ocaml/'&gt;languages&lt;/a&gt; is pattern matching. It often allows for very succinct and elegant declarative expressions, and in the dynamic variants it allows for easy in-line lightweight type checking.&lt;/p&gt;

&lt;p&gt;So, naturally I wanted the same in Python, the programming language we use at work.&lt;/p&gt;

&lt;p&gt;Pattern matching is most powerful when it enjoys first-class support in a language. In addition to succinct syntax, this affords you the ability to integrate pattern matchers with control constructs, allowing conditional execution of code based on various patterns. It also may give you a degree of composability not possible otherwise. For example, &lt;a href='http://www.erlang.org/'&gt;Erlang&lt;/a&gt; has not only a &lt;code&gt;case&lt;/code&gt; statement, but allows for &lt;em&gt;clauses&lt;/em&gt; in functions, so that pattern matching is done on the arguments of functions with the same name and arity. For instance in Erlang, you could implement a simple REST-style HTTP request handlers like so:&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;span class='c'&gt;%% handle(Path, Method)&lt;/span&gt;
&lt;span class='nf'&gt;handle&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='s'&gt;&amp;quot;/&amp;quot;&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='p'&gt;_)&lt;/span&gt; &lt;span class='o'&gt;-&amp;gt;&lt;/span&gt;
  &lt;span class='n'&gt;not_a_resource&lt;/span&gt;&lt;span class='p'&gt;;&lt;/span&gt;
&lt;span class='nf'&gt;handle&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='nv'&gt;Path&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='n'&gt;&amp;#39;PUT&amp;#39;&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt; &lt;span class='o'&gt;-&amp;gt;&lt;/span&gt;
  &lt;span class='n'&gt;create_new_resource&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='nv'&gt;Path&lt;/span&gt;&lt;span class='p'&gt;);&lt;/span&gt;
&lt;span class='nf'&gt;handle&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='nv'&gt;Path&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='n'&gt;&amp;#39;POST&amp;#39;&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt; &lt;span class='o'&gt;-&amp;gt;&lt;/span&gt;
  &lt;span class='n'&gt;update_resource&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='nv'&gt;Path&lt;/span&gt;&lt;span class='p'&gt;);&lt;/span&gt;
&lt;span class='nf'&gt;handle&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='nv'&gt;Path&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='n'&gt;&amp;#39;GET&amp;#39;&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt; &lt;span class='o'&gt;-&amp;gt;&lt;/span&gt;
  &lt;span class='n'&gt;retrieve_resource&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='nv'&gt;Path&lt;/span&gt;&lt;span class='p'&gt;);&lt;/span&gt;
&lt;span class='nf'&gt;handle&lt;/span&gt;&lt;span class='p'&gt;(_,&lt;/span&gt; &lt;span class='p'&gt;_)&lt;/span&gt; &lt;span class='o'&gt;-&amp;gt;&lt;/span&gt;
  &lt;span class='n'&gt;invalid_request&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;
&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;Now I can simply call &lt;code&gt;handle(Path, Method)&lt;/code&gt; to deal with my request. Notice also how powerful ordering is here: I exclude the resource &lt;code&gt;&amp;quot;/&amp;quot;&lt;/code&gt; entirely by matching on it first. Note also that some arguments here are &lt;em&gt;binding&lt;/em&gt;, while others are not. For example in the first clause, nothing is bound, in the second, we bind &lt;code&gt;Path&lt;/code&gt; if the method matches &lt;code&gt;&amp;#39;PUT&amp;#39;&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;How do we graft something like this onto a language like Python? It&amp;#8217;s especially tricky because we&amp;#8217;d like to maintain the ever elusive &amp;#8220;Pythonics.&amp;#8221; While I&amp;#8217;m quite sure Guido would never even touch this stuff, we can at least maintain the spirit! Start off by importing the match primitives:&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;span class='o'&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class='kn'&gt;from&lt;/span&gt; &lt;span class='nn'&gt;match&lt;/span&gt; &lt;span class='kn'&gt;import&lt;/span&gt; &lt;span class='n'&gt;M&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='n'&gt;A&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='n'&gt;A_&lt;/span&gt;
&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;&lt;code&gt;M&lt;/code&gt; creates a destructuring match expression (a &amp;#8220;matcher&amp;#8221;), &lt;code&gt;A&lt;/code&gt; is the a binding argument, and &lt;code&gt;A_&lt;/code&gt; is the &amp;#8220;any&amp;#8221; argument. Any &lt;code&gt;A&lt;/code&gt; arguments need to have a positional specifier. This is achieved with the division operator. So &lt;code&gt;A/0&lt;/code&gt; names the first value in the returned destructured tuple. With the help of a few operators, we compose a match expression:&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;span class='o'&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class='n'&gt;M&lt;/span&gt;&lt;span class='p'&gt;((&lt;/span&gt;&lt;span class='mi'&gt;1&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='n'&gt;A_&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='mi'&gt;3&lt;/span&gt;&lt;span class='p'&gt;),&lt;/span&gt; &lt;span class='n'&gt;A&lt;/span&gt;&lt;span class='o'&gt;/&lt;/span&gt;&lt;span class='mi'&gt;1&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='n'&gt;A&lt;/span&gt;&lt;span class='o'&gt;/&lt;/span&gt;&lt;span class='mi'&gt;0&lt;/span&gt;&lt;span class='p'&gt;))&lt;/span&gt;
&lt;span class='o'&gt;&amp;lt;&lt;/span&gt;&lt;span class='n'&gt;match&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;M&lt;/span&gt; &lt;span class='nb'&gt;object&lt;/span&gt; &lt;span class='n'&gt;at&lt;/span&gt; &lt;span class='mh'&gt;0x726f0&lt;/span&gt;&lt;span class='o'&gt;&amp;gt;&lt;/span&gt;
&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;So, these expressions are entirely useless until they are &lt;em&gt;bound&lt;/em&gt;. The &lt;code&gt;==&lt;/code&gt; operator takes care of that:&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;span class='o'&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class='n'&gt;M&lt;/span&gt;&lt;span class='p'&gt;((&lt;/span&gt;&lt;span class='mi'&gt;1&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='n'&gt;A_&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='mi'&gt;3&lt;/span&gt;&lt;span class='p'&gt;),&lt;/span&gt; &lt;span class='n'&gt;A&lt;/span&gt;&lt;span class='o'&gt;/&lt;/span&gt;&lt;span class='mi'&gt;1&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='n'&gt;A&lt;/span&gt;&lt;span class='o'&gt;/&lt;/span&gt;&lt;span class='mi'&gt;0&lt;/span&gt;&lt;span class='p'&gt;))&lt;/span&gt; &lt;span class='o'&gt;==&lt;/span&gt; &lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='mi'&gt;1&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='mi'&gt;2&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='mi'&gt;3&lt;/span&gt;&lt;span class='p'&gt;),&lt;/span&gt; &lt;span class='mi'&gt;1&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='mi'&gt;2&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt;
&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='mi'&gt;2&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='mi'&gt;1&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt;
&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;If you precede the match-expression with the &lt;code&gt;~&lt;/code&gt; operator, the expression becomes a &amp;#8220;pure&amp;#8221; matching expression, and does not destructure the second operand, it just returns &lt;code&gt;True&lt;/code&gt; or &lt;code&gt;False&lt;/code&gt; depending on whether it matched successfully.&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;span class='o'&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class='o'&gt;~&lt;/span&gt;&lt;span class='n'&gt;M&lt;/span&gt;&lt;span class='p'&gt;((&lt;/span&gt;&lt;span class='mi'&gt;1&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='n'&gt;A_&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='mi'&gt;3&lt;/span&gt;&lt;span class='p'&gt;),&lt;/span&gt; &lt;span class='n'&gt;A&lt;/span&gt;&lt;span class='o'&gt;/&lt;/span&gt;&lt;span class='mi'&gt;1&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='n'&gt;A&lt;/span&gt;&lt;span class='o'&gt;/&lt;/span&gt;&lt;span class='mi'&gt;0&lt;/span&gt;&lt;span class='p'&gt;))&lt;/span&gt; &lt;span class='o'&gt;==&lt;/span&gt; &lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='mi'&gt;1&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='mi'&gt;2&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='mi'&gt;3&lt;/span&gt;&lt;span class='p'&gt;),&lt;/span&gt; &lt;span class='mi'&gt;1&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='mi'&gt;2&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt;
&lt;span class='bp'&gt;True&lt;/span&gt;
&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;Now, to make things more interesting, match-expressions can be &lt;code&gt;or&lt;/code&gt;-ed together, resulting in the first successful match. For example &lt;code&gt;M([A/0]) | M(A/0)&lt;/code&gt; doesn&amp;#8217;t care whether the value is a list of length 1 or a literal.&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;span class='o'&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class='n'&gt;M&lt;/span&gt;&lt;span class='p'&gt;([&lt;/span&gt;&lt;span class='n'&gt;A&lt;/span&gt;&lt;span class='o'&gt;/&lt;/span&gt;&lt;span class='mi'&gt;0&lt;/span&gt;&lt;span class='p'&gt;])&lt;/span&gt; &lt;span class='o'&gt;|&lt;/span&gt; &lt;span class='n'&gt;M&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='n'&gt;A&lt;/span&gt;&lt;span class='o'&gt;/&lt;/span&gt;&lt;span class='mi'&gt;0&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt; &lt;span class='o'&gt;==&lt;/span&gt; &lt;span class='p'&gt;[&lt;/span&gt;&lt;span class='mi'&gt;5&lt;/span&gt;&lt;span class='p'&gt;]&lt;/span&gt;
&lt;span class='mi'&gt;5&lt;/span&gt;
&lt;span class='o'&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class='n'&gt;M&lt;/span&gt;&lt;span class='p'&gt;([&lt;/span&gt;&lt;span class='n'&gt;A&lt;/span&gt;&lt;span class='o'&gt;/&lt;/span&gt;&lt;span class='mi'&gt;0&lt;/span&gt;&lt;span class='p'&gt;])&lt;/span&gt; &lt;span class='o'&gt;|&lt;/span&gt; &lt;span class='n'&gt;M&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='n'&gt;A&lt;/span&gt;&lt;span class='o'&gt;/&lt;/span&gt;&lt;span class='mi'&gt;0&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt; &lt;span class='o'&gt;==&lt;/span&gt; &lt;span class='mi'&gt;5&lt;/span&gt;
&lt;span class='mi'&gt;5&lt;/span&gt;
&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;Finally, matchers can specify &amp;#8220;default&amp;#8221; values to be returned they match successfully. This is to help deal with polymorphic return values. For example, the following expression:&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;span class='o'&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class='n'&gt;M&lt;/span&gt;&lt;span class='p'&gt;([&lt;/span&gt;&lt;span class='n'&gt;A&lt;/span&gt;&lt;span class='o'&gt;/&lt;/span&gt;&lt;span class='mi'&gt;0&lt;/span&gt;&lt;span class='p'&gt;])&lt;/span&gt; &lt;span class='o'&gt;|&lt;/span&gt; &lt;span class='n'&gt;M&lt;/span&gt;&lt;span class='p'&gt;([],&lt;/span&gt; &lt;span class='n'&gt;d&lt;/span&gt;&lt;span class='o'&gt;=&lt;/span&gt;&lt;span class='bp'&gt;False&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt; &lt;span class='o'&gt;==&lt;/span&gt; &lt;span class='n'&gt;arr&lt;/span&gt;&lt;span class='p'&gt;[:&lt;/span&gt;&lt;span class='mi'&gt;1&lt;/span&gt;&lt;span class='p'&gt;]&lt;/span&gt;
&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;picks the first element if &lt;code&gt;arr&lt;/code&gt; is nonempty, otherwise it returns &lt;code&gt;False&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;I&amp;#8217;ve put the &lt;a href='http://github.com/mariusaeriksen/match/tree/master'&gt;code up on GitHub&lt;/a&gt;. I&amp;#8217;m not super happy with the aesthetics of it but it&amp;#8217;s interesting to experiment with. Among other things, it definitely needs list and dictionary destructuring.&lt;/p&gt;</content>
  </entry>
  

</feed>
