<?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>2010-09-13T00:18:53-07:00</updated>
  <id>http://monkey.org/~marius</id>
  <author>
    <name>marius a. eriksen</name>
    <email>marius@monkey.org</email>
  </author>

  
  <atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" type="application/atom+xml" href="http://feeds.feedburner.com/mariusaeriksen" /><feedburner:info xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" uri="mariusaeriksen" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com/" /><entry>
    <title>Implementing python style generators with delimited continuations</title>
    <link href="http://monkey.org/~marius/implementing-python-style-generators-with-delimited-continuations.html" />
    <updated>2010-09-12T00:00:00-07:00</updated>
    <id>http://monkey.org/~marius/./implementing-python-style-generators-with-delimited-continuations</id>
    <content type="html">&lt;p&gt;&lt;a href='http://ambassadortothecomputers.blogspot.com/2010/08/mixing-monadic-and-direct-style-code.html'&gt;Jake&amp;#8217;s article&lt;/a&gt; on implementing LWT-compatible fibers with &lt;a href='http://okmij.org/ftp/continuations/caml-shift.pdf'&gt;Oleg&amp;#8217;s delimited continuation library&lt;/a&gt; got me thinking about one of my favorite Python features: &lt;a href='http://docs.python.org/tutorial/classes.html#generators'&gt;generators&lt;/a&gt;.&lt;/p&gt;

&lt;h2 id='delimited_continuations'&gt;Delimited continuations&lt;/h2&gt;

&lt;p&gt;Delimited continuations have a very simple API (note: I&amp;#8217;m going to consider only the high level API provided by &lt;code&gt;delimcc&lt;/code&gt; here consistent with the abstract view of delimited continuations. Jake describes the low-level API in &lt;a href='http://ambassadortothecomputers.blogspot.com/2010/08/mixing-monadic-and-direct-style-code.html'&gt;his article&lt;/a&gt;). The core API is:&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;span class='k'&gt;val&lt;/span&gt; &lt;span class='n'&gt;new_prompt&lt;/span&gt;   &lt;span class='o'&gt;:&lt;/span&gt; &lt;span class='kt'&gt;unit&lt;/span&gt; &lt;span class='o'&gt;-&amp;gt;&lt;/span&gt; &lt;span class='k'&gt;&amp;#39;&lt;/span&gt;&lt;span class='n'&gt;a&lt;/span&gt; &lt;span class='n'&gt;prompt&lt;/span&gt;
&lt;span class='k'&gt;val&lt;/span&gt; &lt;span class='n'&gt;push_prompt&lt;/span&gt;  &lt;span class='o'&gt;:&lt;/span&gt; &lt;span class='k'&gt;&amp;#39;&lt;/span&gt;&lt;span class='n'&gt;a&lt;/span&gt; &lt;span class='n'&gt;prompt&lt;/span&gt; &lt;span class='o'&gt;-&amp;gt;&lt;/span&gt; &lt;span class='o'&gt;(&lt;/span&gt;&lt;span class='kt'&gt;unit&lt;/span&gt; &lt;span class='o'&gt;-&amp;gt;&lt;/span&gt; &lt;span class='k'&gt;&amp;#39;&lt;/span&gt;&lt;span class='n'&gt;a&lt;/span&gt;&lt;span class='o'&gt;)&lt;/span&gt; &lt;span class='o'&gt;-&amp;gt;&lt;/span&gt; &lt;span class='k'&gt;&amp;#39;&lt;/span&gt;&lt;span class='n'&gt;a&lt;/span&gt;
&lt;span class='k'&gt;val&lt;/span&gt; &lt;span class='n'&gt;shift0&lt;/span&gt;       &lt;span class='o'&gt;:&lt;/span&gt; &lt;span class='k'&gt;&amp;#39;&lt;/span&gt;&lt;span class='n'&gt;a&lt;/span&gt; &lt;span class='n'&gt;prompt&lt;/span&gt; &lt;span class='o'&gt;-&amp;gt;&lt;/span&gt; &lt;span class='o'&gt;((&lt;/span&gt;&lt;span class='k'&gt;&amp;#39;&lt;/span&gt;&lt;span class='n'&gt;b&lt;/span&gt; &lt;span class='o'&gt;-&amp;gt;&lt;/span&gt; &lt;span class='k'&gt;&amp;#39;&lt;/span&gt;&lt;span class='n'&gt;a&lt;/span&gt;&lt;span class='o'&gt;)&lt;/span&gt; &lt;span class='o'&gt;-&amp;gt;&lt;/span&gt; &lt;span class='k'&gt;&amp;#39;&lt;/span&gt;&lt;span class='n'&gt;a&lt;/span&gt;&lt;span class='o'&gt;)&lt;/span&gt; &lt;span class='o'&gt;-&amp;gt;&lt;/span&gt; &lt;span class='k'&gt;&amp;#39;&lt;/span&gt;&lt;span class='n'&gt;b&lt;/span&gt;
&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;&lt;code&gt;new_prompt&lt;/code&gt; simply creates the &amp;#8220;handle&amp;#8221;, &lt;code&gt;push_prompt&lt;/code&gt; (traditionally called &lt;code&gt;reset&lt;/code&gt;) sets the limit of the continuation (how far up the stack we will go), &lt;code&gt;shift0&lt;/code&gt; captures the continuation and gives it to the passed function. Crucially, the continuation captured by &lt;code&gt;shift0&lt;/code&gt; is &lt;em&gt;delimited&lt;/em&gt; by the outer &lt;code&gt;push_prompt&lt;/code&gt;. The &amp;#8220;region&amp;#8221; of the continuation delimited by &lt;code&gt;push_prompt&lt;/code&gt; and &lt;code&gt;shift0&lt;/code&gt; consists of the stack frames between the two (this also means you cannot call &lt;code&gt;shift0&lt;/code&gt; anywhere outside the scope of &lt;code&gt;push_prompt&lt;/code&gt;).&lt;/p&gt;

&lt;p&gt;An example should clarify. Let&amp;#8217;s first do something illegal.&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;span class='o'&gt;#&lt;/span&gt; &lt;span class='k'&gt;open&lt;/span&gt; &lt;span class='nc'&gt;Delimcc&lt;/span&gt;&lt;span class='o'&gt;;;&lt;/span&gt;
&lt;span class='o'&gt;#&lt;/span&gt; &lt;span class='k'&gt;let&lt;/span&gt; &lt;span class='n'&gt;p&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='n'&gt;new_prompt&lt;/span&gt; &lt;span class='bp'&gt;()&lt;/span&gt;&lt;span class='o'&gt;;;&lt;/span&gt;
&lt;span class='n'&gt;value&lt;/span&gt; &lt;span class='n'&gt;p&lt;/span&gt; &lt;span class='o'&gt;:&lt;/span&gt; &lt;span class='nn'&gt;Delimcc&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='n'&gt;prompt&lt;/span&gt; &lt;span class='k'&gt;&amp;#39;&lt;/span&gt;&lt;span class='o'&gt;_&lt;/span&gt;&lt;span class='n'&gt;a&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='o'&gt;&amp;lt;&lt;/span&gt;&lt;span class='n'&gt;abstr&lt;/span&gt;&lt;span class='o'&gt;&amp;gt;&lt;/span&gt;
&lt;span class='o'&gt;#&lt;/span&gt; &lt;span class='n'&gt;push_prompt&lt;/span&gt; &lt;span class='n'&gt;p&lt;/span&gt; &lt;span class='n'&gt;identity&lt;/span&gt;&lt;span class='o'&gt;;;&lt;/span&gt;
&lt;span class='o'&gt;-&lt;/span&gt; &lt;span class='o'&gt;:&lt;/span&gt; &lt;span class='kt'&gt;unit&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='bp'&gt;()&lt;/span&gt;
&lt;span class='o'&gt;#&lt;/span&gt; &lt;span class='n'&gt;shift0&lt;/span&gt; &lt;span class='n'&gt;p&lt;/span&gt; &lt;span class='o'&gt;(&lt;/span&gt;&lt;span class='k'&gt;fun&lt;/span&gt; &lt;span class='n'&gt;k&lt;/span&gt; &lt;span class='o'&gt;-&amp;gt;&lt;/span&gt; &lt;span class='n'&gt;k&lt;/span&gt; &lt;span class='bp'&gt;()&lt;/span&gt;&lt;span class='o'&gt;);;&lt;/span&gt;
&lt;span class='nc'&gt;Exception&lt;/span&gt;&lt;span class='o'&gt;:&lt;/span&gt; &lt;span class='nc'&gt;Failure&lt;/span&gt; &lt;span class='s2'&gt;&amp;quot;No prompt was set&amp;quot;&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;
&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;Here, we tried to &lt;code&gt;shift0&lt;/code&gt; outside of the &lt;code&gt;push_prompt&lt;/code&gt;. Nope, can&amp;#8217;t do that.&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;span class='o'&gt;#&lt;/span&gt; &lt;span class='n'&gt;push_prompt&lt;/span&gt; &lt;span class='n'&gt;p&lt;/span&gt; &lt;span class='o'&gt;(&lt;/span&gt;&lt;span class='k'&gt;fun&lt;/span&gt; &lt;span class='bp'&gt;()&lt;/span&gt; &lt;span class='o'&gt;-&amp;gt;&lt;/span&gt; &lt;span class='n'&gt;shift0&lt;/span&gt; &lt;span class='n'&gt;p&lt;/span&gt; &lt;span class='o'&gt;(&lt;/span&gt;&lt;span class='k'&gt;fun&lt;/span&gt; &lt;span class='n'&gt;k&lt;/span&gt; &lt;span class='o'&gt;-&amp;gt;&lt;/span&gt; &lt;span class='n'&gt;k&lt;/span&gt; &lt;span class='mi'&gt;123&lt;/span&gt;&lt;span class='o'&gt;));;&lt;/span&gt;
&lt;span class='o'&gt;-&lt;/span&gt; &lt;span class='o'&gt;:&lt;/span&gt; &lt;span class='kt'&gt;int&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='mi'&gt;123&lt;/span&gt;
&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;Here, the inner function (passed to &lt;code&gt;shift0&lt;/code&gt;) was given the captured continuation &lt;code&gt;k&lt;/code&gt; (as delimited by &lt;code&gt;push_prompt&lt;/code&gt;), calling it with the argument &lt;code&gt;123&lt;/code&gt; which was subsequently returned.&lt;/p&gt;

&lt;p&gt;The neat thing about delimited continuations is that they &lt;em&gt;capture the state entire delimited stack&lt;/em&gt;. That is, calling &lt;code&gt;k ARG&lt;/code&gt; from within &lt;code&gt;shift0&lt;/code&gt; is equivalent to replacing the &lt;code&gt;shift0&lt;/code&gt; statement with &lt;code&gt;ARG&lt;/code&gt;, returning the result of &lt;code&gt;push_prompt&lt;/code&gt;. Furthermore, it&amp;#8217;s a first class continuation, so we may use it multiple times. To wit:&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;span class='o'&gt;#&lt;/span&gt; &lt;span class='n'&gt;push_prompt&lt;/span&gt; &lt;span class='n'&gt;p&lt;/span&gt; &lt;span class='o'&gt;(&lt;/span&gt;&lt;span class='k'&gt;fun&lt;/span&gt; &lt;span class='bp'&gt;()&lt;/span&gt; &lt;span class='o'&gt;-&amp;gt;&lt;/span&gt; &lt;span class='mi'&gt;10&lt;/span&gt; &lt;span class='o'&gt;*&lt;/span&gt; &lt;span class='n'&gt;shift0&lt;/span&gt; &lt;span class='n'&gt;p&lt;/span&gt; &lt;span class='o'&gt;(&lt;/span&gt;&lt;span class='k'&gt;fun&lt;/span&gt; &lt;span class='n'&gt;k&lt;/span&gt; &lt;span class='o'&gt;-&amp;gt;&lt;/span&gt; &lt;span class='n'&gt;k&lt;/span&gt; &lt;span class='mi'&gt;1&lt;/span&gt; &lt;span class='o'&gt;+&lt;/span&gt; &lt;span class='n'&gt;k&lt;/span&gt; &lt;span class='mi'&gt;3&lt;/span&gt;&lt;span class='o'&gt;));;&lt;/span&gt;
&lt;span class='o'&gt;-&lt;/span&gt; &lt;span class='o'&gt;:&lt;/span&gt; &lt;span class='kt'&gt;int&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='mi'&gt;40&lt;/span&gt;
&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;Here, &lt;code&gt;k&lt;/code&gt; is equivalent to the function &lt;code&gt;( * ) 10&lt;/code&gt;. The argument &amp;amp; return types needn&amp;#8217;t be uniform:&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;span class='o'&gt;#&lt;/span&gt; &lt;span class='n'&gt;push_prompt&lt;/span&gt; &lt;span class='n'&gt;p&lt;/span&gt; &lt;span class='o'&gt;(&lt;/span&gt;&lt;span class='k'&gt;fun&lt;/span&gt; &lt;span class='bp'&gt;()&lt;/span&gt; &lt;span class='o'&gt;-&amp;gt;&lt;/span&gt; &lt;span class='n'&gt;string_of_int&lt;/span&gt; &lt;span class='o'&gt;(&lt;/span&gt;&lt;span class='n'&gt;shift0&lt;/span&gt; &lt;span class='n'&gt;p&lt;/span&gt; &lt;span class='o'&gt;(&lt;/span&gt;&lt;span class='k'&gt;fun&lt;/span&gt; &lt;span class='n'&gt;k&lt;/span&gt; &lt;span class='o'&gt;-&amp;gt;&lt;/span&gt;  &lt;span class='s2'&gt;&amp;quot;hey &amp;quot;&lt;/span&gt; &lt;span class='o'&gt;^&lt;/span&gt; &lt;span class='n'&gt;k&lt;/span&gt; &lt;span class='mi'&gt;123&lt;/span&gt;&lt;span class='o'&gt;)));;&lt;/span&gt;
&lt;span class='o'&gt;-&lt;/span&gt; &lt;span class='o'&gt;:&lt;/span&gt; &lt;span class='kt'&gt;string&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='s2'&gt;&amp;quot;hey 123&amp;quot;&lt;/span&gt;
&lt;/pre&gt;
&lt;/div&gt;
&lt;h2 id='leaking_continuations'&gt;Leaking continuations&lt;/h2&gt;

&lt;p&gt;What makes delimited continuations yet more interesting is that the continuations themselves can escape the scope of &lt;code&gt;shift0&lt;/code&gt;, and be restarted from outside.&lt;/p&gt;

&lt;p&gt;Because of the type signatures of &lt;code&gt;shift0&lt;/code&gt;, we need to unify the types, so let&amp;#8217;s first define an ADT to do so:&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;span class='o'&gt;#&lt;/span&gt; &lt;span class='k'&gt;type&lt;/span&gt; &lt;span class='n'&gt;t&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='nc'&gt;Done&lt;/span&gt; &lt;span class='o'&gt;|&lt;/span&gt; &lt;span class='nc'&gt;More&lt;/span&gt; &lt;span class='k'&gt;of&lt;/span&gt; &lt;span class='o'&gt;(&lt;/span&gt;&lt;span class='kt'&gt;unit&lt;/span&gt; &lt;span class='o'&gt;-&amp;gt;&lt;/span&gt; &lt;span class='n'&gt;t&lt;/span&gt;&lt;span class='o'&gt;);;&lt;/span&gt;
&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;Note that we can&amp;#8217;t just use &lt;code&gt;option&lt;/code&gt; here, it seems, because we need a recursive type.&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;span class='o'&gt;#&lt;/span&gt; &lt;span class='k'&gt;let&lt;/span&gt; &lt;span class='n'&gt;count&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='n'&gt;ref&lt;/span&gt; &lt;span class='mi'&gt;0&lt;/span&gt;&lt;span class='o'&gt;;;&lt;/span&gt;
&lt;span class='o'&gt;#&lt;/span&gt; &lt;span class='k'&gt;let&lt;/span&gt; &lt;span class='nc'&gt;More&lt;/span&gt; &lt;span class='n'&gt;k&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='n'&gt;push_prompt&lt;/span&gt; &lt;span class='n'&gt;p&lt;/span&gt; &lt;span class='o'&gt;(&lt;/span&gt;&lt;span class='k'&gt;fun&lt;/span&gt; &lt;span class='bp'&gt;()&lt;/span&gt; &lt;span class='o'&gt;-&amp;gt;&lt;/span&gt; 
  &lt;span class='k'&gt;while&lt;/span&gt; &lt;span class='bp'&gt;true&lt;/span&gt; &lt;span class='k'&gt;do&lt;/span&gt; 
    &lt;span class='n'&gt;count&lt;/span&gt; &lt;span class='o'&gt;:=&lt;/span&gt; &lt;span class='o'&gt;!&lt;/span&gt;&lt;span class='n'&gt;count&lt;/span&gt; &lt;span class='o'&gt;+&lt;/span&gt; &lt;span class='mi'&gt;1&lt;/span&gt;&lt;span class='o'&gt;;&lt;/span&gt; 
    &lt;span class='n'&gt;shift0&lt;/span&gt; &lt;span class='n'&gt;p&lt;/span&gt; &lt;span class='o'&gt;(&lt;/span&gt;&lt;span class='k'&gt;fun&lt;/span&gt; &lt;span class='n'&gt;k&lt;/span&gt; &lt;span class='o'&gt;-&amp;gt;&lt;/span&gt; &lt;span class='nc'&gt;More&lt;/span&gt; &lt;span class='n'&gt;k&lt;/span&gt;&lt;span class='o'&gt;)&lt;/span&gt;
  &lt;span class='k'&gt;done&lt;/span&gt;&lt;span class='o'&gt;;&lt;/span&gt; 
  &lt;span class='nc'&gt;Done&lt;/span&gt;&lt;span class='o'&gt;);;&lt;/span&gt;
&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;Here we are using our unified type trick to return the continuation itself (note how &lt;code&gt;push_prompt&lt;/code&gt; and &lt;code&gt;shift&lt;/code&gt; have the same return type). Let&amp;#8217;s play!&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;span class='o'&gt;#&lt;/span&gt; &lt;span class='o'&gt;!&lt;/span&gt;&lt;span class='n'&gt;count&lt;/span&gt;&lt;span class='o'&gt;;;&lt;/span&gt;
&lt;span class='o'&gt;-&lt;/span&gt; &lt;span class='o'&gt;:&lt;/span&gt; &lt;span class='kt'&gt;int&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='mi'&gt;1&lt;/span&gt;
&lt;span class='o'&gt;#&lt;/span&gt; &lt;span class='n'&gt;k&lt;/span&gt; &lt;span class='bp'&gt;()&lt;/span&gt;&lt;span class='o'&gt;;;&lt;/span&gt;
&lt;span class='o'&gt;-&lt;/span&gt; &lt;span class='o'&gt;:&lt;/span&gt; &lt;span class='n'&gt;t&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='nc'&gt;More&lt;/span&gt; &lt;span class='o'&gt;&amp;lt;&lt;/span&gt;&lt;span class='k'&gt;fun&lt;/span&gt;&lt;span class='o'&gt;&amp;gt;&lt;/span&gt;
&lt;span class='o'&gt;#&lt;/span&gt; &lt;span class='n'&gt;k&lt;/span&gt; &lt;span class='bp'&gt;()&lt;/span&gt;&lt;span class='o'&gt;;;&lt;/span&gt;
&lt;span class='o'&gt;-&lt;/span&gt; &lt;span class='o'&gt;:&lt;/span&gt; &lt;span class='n'&gt;t&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='nc'&gt;More&lt;/span&gt; &lt;span class='o'&gt;&amp;lt;&lt;/span&gt;&lt;span class='k'&gt;fun&lt;/span&gt;&lt;span class='o'&gt;&amp;gt;&lt;/span&gt;
&lt;span class='o'&gt;#&lt;/span&gt; &lt;span class='o'&gt;!&lt;/span&gt;&lt;span class='n'&gt;count&lt;/span&gt;&lt;span class='o'&gt;;;&lt;/span&gt;
&lt;span class='o'&gt;-&lt;/span&gt; &lt;span class='o'&gt;:&lt;/span&gt; &lt;span class='kt'&gt;int&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='mi'&gt;3&lt;/span&gt;
&lt;/pre&gt;
&lt;/div&gt;
&lt;h2 id='generators'&gt;Generators&lt;/h2&gt;

&lt;p&gt;We now have a pretty good idea of what&amp;#8217;s needed to implement generators with an API similar to:&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;span class='k'&gt;let&lt;/span&gt; &lt;span class='n'&gt;producer&lt;/span&gt; &lt;span class='bp'&gt;()&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt;
  &lt;span class='k'&gt;let&lt;/span&gt; &lt;span class='n'&gt;state&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='o'&gt;...&lt;/span&gt; &lt;span class='k'&gt;in&lt;/span&gt;
  &lt;span class='n'&gt;gen&lt;/span&gt; &lt;span class='k'&gt;begin&lt;/span&gt; &lt;span class='k'&gt;fun&lt;/span&gt; &lt;span class='n'&gt;yield&lt;/span&gt; &lt;span class='o'&gt;-&amp;gt;&lt;/span&gt;
    &lt;span class='n'&gt;yield&lt;/span&gt; &lt;span class='n'&gt;state&lt;/span&gt;&lt;span class='o'&gt;;&lt;/span&gt; &lt;span class='o'&gt;...;&lt;/span&gt; &lt;span class='n'&gt;yield&lt;/span&gt; &lt;span class='n'&gt;state&lt;/span&gt;&lt;span class='o'&gt;;&lt;/span&gt; &lt;span class='o'&gt;...;&lt;/span&gt; &lt;span class='n'&gt;yield&lt;/span&gt; &lt;span class='n'&gt;state&lt;/span&gt;
  &lt;span class='k'&gt;end&lt;/span&gt;
&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;So we need a function &lt;code&gt;gen&lt;/code&gt; that takes a &amp;#8220;yielder&amp;#8221; (in Python terminology) that needs to capture the continuation, communicate the value and resume execution when the next value is asked for by the consumer:&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;span class='k'&gt;let&lt;/span&gt; &lt;span class='n'&gt;consumer&lt;/span&gt; &lt;span class='bp'&gt;()&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; 
  &lt;span class='k'&gt;let&lt;/span&gt; &lt;span class='n'&gt;g&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='n'&gt;producer&lt;/span&gt; &lt;span class='bp'&gt;()&lt;/span&gt; &lt;span class='k'&gt;in&lt;/span&gt;
  &lt;span class='k'&gt;let&lt;/span&gt; &lt;span class='n'&gt;v0&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='n'&gt;g&lt;/span&gt; &lt;span class='bp'&gt;()&lt;/span&gt; &lt;span class='k'&gt;in&lt;/span&gt;
  &lt;span class='o'&gt;...&lt;/span&gt;
  &lt;span class='k'&gt;let&lt;/span&gt; &lt;span class='n'&gt;vN&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='n'&gt;g&lt;/span&gt; &lt;span class='bp'&gt;()&lt;/span&gt;
&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;It turns out that this is a very natural fit, and we can implement full duplex generators in just a few lines, using the ideas developed above. Here is the full source code:&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;span class='k'&gt;type&lt;/span&gt; &lt;span class='o'&gt;(&lt;/span&gt;&lt;span class='k'&gt;&amp;#39;&lt;/span&gt;&lt;span class='n'&gt;a&lt;/span&gt;&lt;span class='o'&gt;,&lt;/span&gt; &lt;span class='k'&gt;&amp;#39;&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;t&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='nc'&gt;Done&lt;/span&gt; &lt;span class='o'&gt;|&lt;/span&gt; &lt;span class='nc'&gt;More&lt;/span&gt; &lt;span class='k'&gt;of&lt;/span&gt; &lt;span class='k'&gt;&amp;#39;&lt;/span&gt;&lt;span class='n'&gt;a&lt;/span&gt; &lt;span class='o'&gt;*&lt;/span&gt; &lt;span class='o'&gt;(&lt;/span&gt;&lt;span class='k'&gt;&amp;#39;&lt;/span&gt;&lt;span class='n'&gt;b&lt;/span&gt; &lt;span class='o'&gt;-&amp;gt;&lt;/span&gt; &lt;span class='o'&gt;(&lt;/span&gt;&lt;span class='k'&gt;&amp;#39;&lt;/span&gt;&lt;span class='n'&gt;a&lt;/span&gt;&lt;span class='o'&gt;,&lt;/span&gt; &lt;span class='k'&gt;&amp;#39;&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;t&lt;/span&gt;&lt;span class='o'&gt;)&lt;/span&gt;

&lt;span class='k'&gt;let&lt;/span&gt; &lt;span class='n'&gt;gen&lt;/span&gt; &lt;span class='n'&gt;f&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt;
  &lt;span class='c'&gt;(*&lt;/span&gt;
&lt;span class='c'&gt;   * Note: the first value to yield gets thrown away as the generator&lt;/span&gt;
&lt;span class='c'&gt;   * has not yet started.&lt;/span&gt;
&lt;span class='c'&gt;   *)&lt;/span&gt;
  &lt;span class='k'&gt;let&lt;/span&gt; &lt;span class='n'&gt;start&lt;/span&gt; &lt;span class='o'&gt;_&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt;
    &lt;span class='k'&gt;let&lt;/span&gt; &lt;span class='n'&gt;p&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='nn'&gt;Delimcc&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='n'&gt;new_prompt&lt;/span&gt; &lt;span class='bp'&gt;()&lt;/span&gt; &lt;span class='k'&gt;in&lt;/span&gt;
    &lt;span class='nn'&gt;Delimcc&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='n'&gt;push_prompt&lt;/span&gt; &lt;span class='n'&gt;p&lt;/span&gt; &lt;span class='k'&gt;begin&lt;/span&gt; &lt;span class='k'&gt;fun&lt;/span&gt; &lt;span class='bp'&gt;()&lt;/span&gt; &lt;span class='o'&gt;-&amp;gt;&lt;/span&gt;
      &lt;span class='n'&gt;f&lt;/span&gt; &lt;span class='o'&gt;(&lt;/span&gt;&lt;span class='k'&gt;fun&lt;/span&gt; &lt;span class='n'&gt;x&lt;/span&gt; &lt;span class='o'&gt;-&amp;gt;&lt;/span&gt; &lt;span class='nn'&gt;Delimcc&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='n'&gt;shift0&lt;/span&gt; &lt;span class='n'&gt;p&lt;/span&gt; &lt;span class='o'&gt;(&lt;/span&gt;&lt;span class='k'&gt;fun&lt;/span&gt; &lt;span class='n'&gt;k&lt;/span&gt; &lt;span class='o'&gt;-&amp;gt;&lt;/span&gt; &lt;span class='nc'&gt;More&lt;/span&gt; &lt;span class='o'&gt;(&lt;/span&gt;&lt;span class='n'&gt;x&lt;/span&gt;&lt;span class='o'&gt;,&lt;/span&gt; &lt;span class='n'&gt;k&lt;/span&gt;&lt;span class='o'&gt;)));&lt;/span&gt; &lt;span class='nc'&gt;Done&lt;/span&gt;
    &lt;span class='k'&gt;end&lt;/span&gt; &lt;span class='k'&gt;in&lt;/span&gt;
  &lt;span class='k'&gt;let&lt;/span&gt; &lt;span class='n'&gt;next&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='n'&gt;ref&lt;/span&gt; &lt;span class='n'&gt;start&lt;/span&gt; &lt;span class='k'&gt;in&lt;/span&gt;

  &lt;span class='k'&gt;fun&lt;/span&gt; &lt;span class='n'&gt;rv&lt;/span&gt; &lt;span class='o'&gt;-&amp;gt;&lt;/span&gt;
    &lt;span class='k'&gt;match&lt;/span&gt; &lt;span class='o'&gt;!&lt;/span&gt;&lt;span class='n'&gt;next&lt;/span&gt; &lt;span class='n'&gt;rv&lt;/span&gt; &lt;span class='k'&gt;with&lt;/span&gt;
      &lt;span class='o'&gt;|&lt;/span&gt; &lt;span class='nc'&gt;More&lt;/span&gt; &lt;span class='o'&gt;(&lt;/span&gt;&lt;span class='n'&gt;x&lt;/span&gt;&lt;span class='o'&gt;,&lt;/span&gt; &lt;span class='n'&gt;k&lt;/span&gt;&lt;span class='o'&gt;)&lt;/span&gt; &lt;span class='o'&gt;-&amp;gt;&lt;/span&gt; &lt;span class='n'&gt;next&lt;/span&gt; &lt;span class='o'&gt;:=&lt;/span&gt; &lt;span class='n'&gt;k&lt;/span&gt;&lt;span class='o'&gt;;&lt;/span&gt; &lt;span class='nc'&gt;Some&lt;/span&gt; &lt;span class='n'&gt;x&lt;/span&gt;
      &lt;span class='o'&gt;|&lt;/span&gt; &lt;span class='nc'&gt;Done&lt;/span&gt;        &lt;span class='o'&gt;-&amp;gt;&lt;/span&gt; &lt;span class='nc'&gt;None&lt;/span&gt;
&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;And sample use:&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;span class='k'&gt;let&lt;/span&gt; &lt;span class='k'&gt;rec&lt;/span&gt; &lt;span class='n'&gt;take_all&lt;/span&gt; &lt;span class='n'&gt;t&lt;/span&gt; &lt;span class='n'&gt;count&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt;
  &lt;span class='k'&gt;match&lt;/span&gt; &lt;span class='n'&gt;t&lt;/span&gt; &lt;span class='n'&gt;count&lt;/span&gt; &lt;span class='k'&gt;with&lt;/span&gt;
    &lt;span class='o'&gt;|&lt;/span&gt; &lt;span class='nc'&gt;Some&lt;/span&gt; &lt;span class='n'&gt;i&lt;/span&gt; &lt;span class='o'&gt;-&amp;gt;&lt;/span&gt; &lt;span class='n'&gt;printf&lt;/span&gt; &lt;span class='s2'&gt;&amp;quot;took: %d&lt;/span&gt;&lt;span class='se'&gt;\n&lt;/span&gt;&lt;span class='s2'&gt;&amp;quot;&lt;/span&gt; &lt;span class='n'&gt;i&lt;/span&gt;&lt;span class='o'&gt;;&lt;/span&gt; &lt;span class='n'&gt;take_all&lt;/span&gt; &lt;span class='n'&gt;t&lt;/span&gt; &lt;span class='o'&gt;(&lt;/span&gt;&lt;span class='n'&gt;count&lt;/span&gt; &lt;span class='o'&gt;+&lt;/span&gt; &lt;span class='mi'&gt;1&lt;/span&gt;&lt;span class='o'&gt;)&lt;/span&gt;
    &lt;span class='o'&gt;|&lt;/span&gt; &lt;span class='nc'&gt;None&lt;/span&gt;   &lt;span class='o'&gt;-&amp;gt;&lt;/span&gt; &lt;span class='bp'&gt;()&lt;/span&gt;

&lt;span class='k'&gt;let&lt;/span&gt; &lt;span class='bp'&gt;()&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt;
  &lt;span class='k'&gt;let&lt;/span&gt; &lt;span class='n'&gt;take&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='n'&gt;gen&lt;/span&gt; &lt;span class='k'&gt;begin&lt;/span&gt; &lt;span class='k'&gt;fun&lt;/span&gt; &lt;span class='n'&gt;yield&lt;/span&gt; &lt;span class='o'&gt;-&amp;gt;&lt;/span&gt;
    &lt;span class='k'&gt;for&lt;/span&gt; &lt;span class='n'&gt;i&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='mi'&gt;0&lt;/span&gt; &lt;span class='k'&gt;to&lt;/span&gt; &lt;span class='mi'&gt;10&lt;/span&gt; &lt;span class='k'&gt;do&lt;/span&gt;
      &lt;span class='k'&gt;let&lt;/span&gt; &lt;span class='n'&gt;rv&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='n'&gt;yield&lt;/span&gt; &lt;span class='n'&gt;i&lt;/span&gt; &lt;span class='k'&gt;in&lt;/span&gt;
      &lt;span class='n'&gt;printf&lt;/span&gt; &lt;span class='s2'&gt;&amp;quot;got: %d&lt;/span&gt;&lt;span class='se'&gt;\n&lt;/span&gt;&lt;span class='s2'&gt;&amp;quot;&lt;/span&gt; &lt;span class='n'&gt;rv&lt;/span&gt;
    &lt;span class='k'&gt;done&lt;/span&gt;
  &lt;span class='k'&gt;end&lt;/span&gt; &lt;span class='k'&gt;in&lt;/span&gt;
  &lt;span class='n'&gt;take_all&lt;/span&gt; &lt;span class='n'&gt;take&lt;/span&gt; &lt;span class='mi'&gt;100&lt;/span&gt;
&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;The only additional work we have to do is to type it for bi-directional communication, and to store the next continuation in a ref cell for the next invocation. Given that the generators developed here are full duplex, we can implement co-routines as outlined in &lt;a href='http://www.python.org/dev/peps/pep-0342/'&gt;PEP 342&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;You can also get it as a gist &lt;a href='http://gist.github.com/576922'&gt;here&lt;/a&gt;. I also highly recommend &lt;a href='http://ambassadortothecomputers.blogspot.com/2010/08/mixing-monadic-and-direct-style-code.html'&gt;Jake&amp;#8217;s article&lt;/a&gt; which explores &lt;code&gt;delimcc&lt;/code&gt; from a lower level of abstraction.&lt;/p&gt;</content>
  </entry>
  
  <entry>
    <title>Self-contained emacs</title>
    <link href="http://monkey.org/~marius/self-contained-emacs.html" />
    <updated>2010-02-21T00:00:00-08:00</updated>
    <id>http://monkey.org/~marius/./self-contained-emacs</id>
    <content type="html">&lt;p&gt;One annoying thing about using emacs on remote systems is the absence of your own initialization &amp;amp; configuration code. It&amp;#8217;s of course possible to push your own, but often it&amp;#8217;s annoying. Configuration often gets rather involved: my own &lt;code&gt;.emacs.d&lt;/code&gt; directory contains many packages and libraries that are not shipped with standard emacs distributions. Another common scenario is that you use shared accounts, making editor configurations rather intrusive.&lt;/p&gt;

&lt;p&gt;So, I sought to simplify the situation.&lt;/p&gt;

&lt;p&gt;&lt;a href='http://github.com/mariusaeriksen/make-emacs'&gt;&lt;code&gt;make-emacs&lt;/code&gt;&lt;/a&gt; creates for you a simple, self-contained and relocatable script that allows you to invoke emacs with your own configuration anywhere. For example:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;    $ make-emacs ~/.emacs.d /tmp/e
    $ scp /tmp/e remoteserver:
    $ ssh remoteserver
    $ ./e MYFILE
    extracting emacs.d..
    &amp;lt;emacs bliss&amp;gt;&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;It uses &lt;a href='http://en.wikipedia.org/wiki/Shar'&gt;shar&lt;/a&gt; to create a self-extracting archive and wraps that extraction code to invoke emacs properly. It also caches the extracted configuration files, so that it only has to perform a potentially costly &lt;code&gt;shar&lt;/code&gt; extraction once.&lt;/p&gt;

&lt;p&gt;Get it on &lt;a href='http://github.com/'&gt;GitHub&lt;/a&gt; &lt;a href='http://github.com/mariusaeriksen/make-emacs'&gt;here&lt;/a&gt;.&lt;/p&gt;</content>
  </entry>
  
  <entry>
    <title>Emacs as a tiling window manager</title>
    <link href="http://monkey.org/~marius/emacs-as-a-tiling-window-manager.html" />
    <updated>2010-01-26T00:00:00-08:00</updated>
    <id>http://monkey.org/~marius/./emacs-as-a-tiling-window-manager</id>
    <content type="html">&lt;p&gt;I&amp;#8217;ve been using &lt;code&gt;emacs&lt;/code&gt; in in full-screen mode lately. It provides a nice, distraction-free environment. If you&amp;#8217;re using &lt;a href='http://homepage.mac.com/zenitani/emacs-e.html'&gt;carbon emacs&lt;/a&gt; it&amp;#8217;s quite easy:&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;(defun mac-toggle-max-window ()
  (interactive)
  (set-frame-parameter nil &amp;#39;fullscreen
                       (if (frame-parameter nil &amp;#39;fullscreen)
                           nil
                         &amp;#39;fullboth)))
(global-set-key (kbd &amp;quot;&amp;lt;C-M-return&amp;gt;&amp;quot;) &amp;#39;mac-toggle-max-window)
&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;I also really enjoy the efficacy of navigation provided by tiling window managers such as &lt;a href='http://xmonad.org/'&gt;xmonad&lt;/a&gt;. So, why not make emacs behave like it?&lt;/p&gt;

&lt;p&gt;&lt;a href='http://gist.github.com/287633'&gt;emacsd-tile.el&lt;/a&gt; is a really tiny configuration snippet to provide just this.&lt;/p&gt;

&lt;p&gt;It provides xmonad-inspired keyboard shortcuts:&lt;/p&gt;
&lt;table&gt;
  &lt;tr&gt;&lt;td&gt;&lt;code&gt;M-{j,k,h,l}&lt;/code&gt;&lt;/td&gt;&lt;td style='padding: 3px;'&gt;&amp;rarr;&lt;/td&gt;&lt;td&gt;move to window (down, up, left, right)&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;&lt;code&gt;M-S-{j,k,h,l}&lt;/code&gt;&lt;/td&gt;&lt;td style='padding: 3px;'&gt;&amp;rarr;&lt;/td&gt;&lt;td&gt;enlarge/shrink horizontally/vertically&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;&lt;code&gt;M-C-{j,k,h,l}&lt;/code&gt;&lt;/td&gt;&lt;td style='padding: 3px;'&gt;&amp;rarr;&lt;/td&gt;&lt;td&gt;swap with (down, up, left, right)&lt;/td&gt;&lt;/tr&gt;
&lt;/table&gt;
&lt;p&gt;This mostly uses just stuff that was already in &lt;code&gt;emacs&lt;/code&gt;! The only part I had to implement myself was window swapping.&lt;/p&gt;

&lt;p&gt;Another really handy feature of emacs is the ability to &lt;a href='http://www.chemie.fu-berlin.de/chemnet/use/info/emacs/emacs_14.html#SEC69'&gt;save window configuration in registers&lt;/a&gt;. With this, you can &amp;#8220;stash&amp;#8221; away an entire window configuration and recall it later.&lt;/p&gt;

&lt;p&gt;Here&amp;#8217;s a &lt;a href='http://monkey.org/~marius/emacs-tile.png'&gt;screenshot&lt;/a&gt;, though it&amp;#8217;s not really descriptive because it doesn&amp;#8217;t show the keybindings in action, but it may convince you that emacs can at least &lt;em&gt;look&lt;/em&gt; like a tiling window manager :-)&lt;/p&gt;

&lt;p&gt;Any other improvements or suggestions?&lt;/p&gt;</content>
  </entry>
  
  <entry>
    <title>Beautiful fixed-width fonts for OSX</title>
    <link href="http://monkey.org/~marius/beautiful-fixed-width-fonts-for-osx.html" />
    <updated>2010-01-10T00:00:00-08:00</updated>
    <id>http://monkey.org/~marius/./beautiful-fixed-width-fonts</id>
    <content type="html">&lt;p&gt;(Or, &lt;em&gt;&amp;#8220;an ode to 9x15&amp;#8221;&lt;/em&gt;)&lt;/p&gt;

&lt;p&gt;I&amp;#8217;ve always had great appreciation for the fixed-width fonts &lt;a href='http://www.cl.cam.ac.uk/~mgk25/ucs-fonts.html'&gt;distributed with X11&lt;/a&gt; (&amp;#8221;&lt;code&gt;misc-fixed-*&lt;/code&gt;&amp;#8221;): 6x13, 7x14, and especially 9x15 (my all-time favorite).&lt;/p&gt;

&lt;p&gt;&lt;img src='images/9x15.png' alt='9x15 in action' /&gt;&lt;/p&gt;

&lt;p&gt;I never really found any type so satisfying. It is extremely crisp and legible, is not dull, and doesn&amp;#8217;t go all fuzzy in its bold variant. Its glyphs are extraordinarily well-suited to the kinds of strange things we tend to do with the ASCII character set in code.&lt;/p&gt;

&lt;p&gt;&lt;img src='images/9x15-code.png' alt='9x15 in code' /&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href='http://www.ccheever.com/blog/?page_id=2'&gt;Charlie Cheever&lt;/a&gt; previously converted &lt;a href='http://www.ccheever.com/blog/?p=135'&gt;9x15 to an OSX dfont&lt;/a&gt;, so I followed suit to fill in with the rest of the sizes using &lt;a href='http://fontforge.sourceforge.net/'&gt;FontForge&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href='http://monkey.org/~marius/x11-misc-fixed.tar.gz'&gt;http://monkey.org/~marius/x11-misc-fixed.tar.gz&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Included are 6x13, 7x14, 9x15 and 10x20. Make sure to use them only with their respective sizes (ie. 13pt for 6x13, 15pt for 9x15 and so on) and without anti aliasing turned on (bolds won&amp;#8217;t render correctly).&lt;/p&gt;

&lt;p&gt;Enjoy!&lt;/p&gt;</content>
  </entry>
  
  <entry>
    <title>Regarding the case against Christopher Thompson</title>
    <link href="http://monkey.org/~marius/regarding-the-case-against-christopher-thompson.html" />
    <updated>2009-11-17T00:00:00-08:00</updated>
    <id>http://monkey.org/~marius/./regarding-the-case-against-christopher-thompson</id>
    <content type="html">&lt;blockquote&gt;
&lt;p&gt;This is a letter sent to the District Attorney in L.A. More information &lt;a href='http://yieldtolife.org/info'&gt;here&lt;/a&gt;.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;hr /&gt;
&lt;p&gt;Greetings,&lt;/p&gt;

&lt;p&gt;I am an avid bicyclist and I think that it is imperative that Christopher Thompson is brought to justice with a penalty fitting the crime he has been convicted of.&lt;/p&gt;

&lt;p&gt;Bicyclists are inherently disadvantaged by size and available protection while riding on public roads. It is dangerous enough while drivers are following the rules. With malicious intent however, the driver is undoubtedly in possession of a very deadly weapon indeed. I believe it is vital for motorists to understand this. By deviating from rule or protocol, the driver has at his hands the capacity to kill. With the addition of malicious intent, the driver almost certainly will.&lt;/p&gt;

&lt;p&gt;The life of the cyclist is at the hands of the motorists around her. Please set the proper precedent by ensuring that Christopher Thompson is penalized to the fullest extent. This is only in proportion to his wildly irresponsible behavior.&lt;/p&gt;

&lt;p&gt;Marius Eriksen of San Francisco, CA.&lt;/p&gt;</content>
  </entry>
  
  <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>
