<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
	<link rel="self" href="/Atom/" />
	<id>http://billmill.org/</id>
	<title>My Name Rhymes</title>
	<subtitle>Bill Mill blogs irregularly</subtitle>
	<updated>2008-01-12T03:32:00Z</updated>
	<author>
		<name>Bill Mill</name>
		<email>bill.mill@gmail.com</email>
		<uri>http://billmill.org/</uri>
	</author>
	<link href="http://billmill.org/" />
	<entry>
		<title>Beautiful Code</title>
		<link href="http://billmill.org/roman.html" />	
		<id>http://billmill.org/roman.html</id>
		<updated>2008-01-12T03:32:00Z</updated>
		<summary type="html">This bit of code for converting numbers into their Roman numeral equivalents 
was posted by &lt;a 
href="http://programming.reddit.com/info/658ys/comments/c02vm1j"&gt;geezusfreeek&lt;/a&gt; 
on reddit, and I found it so alarmingly pretty that I'm going to spend some 
time to break it down.  This exercise is largely for my own edification, but 
perhaps somebody else will learn a bit along the way. Here's the code:
&lt;p&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span style="font-weight: bold"&gt;import&lt;/span&gt; &lt;span style="color: #555555"&gt;List&lt;/span&gt;
&lt;span style="font-weight: bold"&gt;import&lt;/span&gt; &lt;span style="color: #555555"&gt;Control.Arrow&lt;/span&gt;

&lt;span style="color: #990000; font-weight: bold"&gt;romanize&lt;/span&gt; &lt;span style="font-weight: bold"&gt;=&lt;/span&gt; concat &lt;span style="font-weight: bold"&gt;.&lt;/span&gt; unfoldr next
    &lt;span style="font-weight: bold"&gt;where&lt;/span&gt; next &lt;span style="color: #009999"&gt;0&lt;/span&gt; &lt;span style="font-weight: bold"&gt;=&lt;/span&gt; &lt;span style="color: #445588; font-weight: bold"&gt;Nothing&lt;/span&gt;
          next x &lt;span style="font-weight: bold"&gt;=&lt;/span&gt; &lt;span style="color: #445588; font-weight: bold"&gt;Just&lt;/span&gt; &lt;span style="font-weight: bold"&gt;$&lt;/span&gt; second (x&lt;span style="font-weight: bold"&gt;-&lt;/span&gt;) &lt;span style="font-weight: bold"&gt;$&lt;/span&gt; head &lt;span style="font-weight: bold"&gt;$&lt;/span&gt; filter ((&lt;span style="font-weight: bold"&gt;&amp;lt;=&lt;/span&gt;x) &lt;span style="font-weight: bold"&gt;.&lt;/span&gt; snd) numerals
          numerals &lt;span style="font-weight: bold"&gt;=&lt;/span&gt; [(&lt;span style="color: #bb8844"&gt;&amp;quot;M&amp;quot;&lt;/span&gt;, &lt;span style="color: #009999"&gt;1000&lt;/span&gt;), (&lt;span style="color: #bb8844"&gt;&amp;quot;CM&amp;quot;&lt;/span&gt;, &lt;span style="color: #009999"&gt;900&lt;/span&gt;), (&lt;span style="color: #bb8844"&gt;&amp;quot;D&amp;quot;&lt;/span&gt;, &lt;span style="color: #009999"&gt;500&lt;/span&gt;), (&lt;span style="color: #bb8844"&gt;&amp;quot;CD&amp;quot;&lt;/span&gt;, &lt;span style="color: #009999"&gt;400&lt;/span&gt;),
                      (&lt;span style="color: #bb8844"&gt;&amp;quot;C&amp;quot;&lt;/span&gt;, &lt;span style="color: #009999"&gt;100&lt;/span&gt;),  (&lt;span style="color: #bb8844"&gt;&amp;quot;XC&amp;quot;&lt;/span&gt;, &lt;span style="color: #009999"&gt;90&lt;/span&gt;),  (&lt;span style="color: #bb8844"&gt;&amp;quot;L&amp;quot;&lt;/span&gt;, &lt;span style="color: #009999"&gt;50&lt;/span&gt;),  (&lt;span style="color: #bb8844"&gt;&amp;quot;XL&amp;quot;&lt;/span&gt;, &lt;span style="color: #009999"&gt;40&lt;/span&gt;),
                      (&lt;span style="color: #bb8844"&gt;&amp;quot;X&amp;quot;&lt;/span&gt;, &lt;span style="color: #009999"&gt;10&lt;/span&gt;),   (&lt;span style="color: #bb8844"&gt;&amp;quot;IX&amp;quot;&lt;/span&gt;, &lt;span style="color: #009999"&gt;9&lt;/span&gt;),   (&lt;span style="color: #bb8844"&gt;&amp;quot;V&amp;quot;&lt;/span&gt;, &lt;span style="color: #009999"&gt;5&lt;/span&gt;),   (&lt;span style="color: #bb8844"&gt;&amp;quot;IV&amp;quot;&lt;/span&gt;, &lt;span style="color: #009999"&gt;4&lt;/span&gt;),
                      (&lt;span style="color: #bb8844"&gt;&amp;quot;I&amp;quot;&lt;/span&gt;, &lt;span style="color: #009999"&gt;1&lt;/span&gt;)]
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Starting from the inside out is usually the easiest method of understanding 
blocks like this, so we'll look first at the "numerals" list. It is, simply, a 
list of tuples matching Roman numerals to their value. Importantly, it's 
ordered from largest to smallest; we'll see why shortly.&lt;/p&gt;
&lt;p&gt;The meat of this snippet comes in the "next" function:
&lt;p&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span style="color: #990000; font-weight: bold"&gt;next&lt;/span&gt; &lt;span style="color: #009999"&gt;0&lt;/span&gt; &lt;span style="font-weight: bold"&gt;=&lt;/span&gt; &lt;span style="color: #445588; font-weight: bold"&gt;Nothing&lt;/span&gt;
&lt;span style="color: #990000; font-weight: bold"&gt;next&lt;/span&gt; x &lt;span style="font-weight: bold"&gt;=&lt;/span&gt; &lt;span style="color: #445588; font-weight: bold"&gt;Just&lt;/span&gt; &lt;span style="font-weight: bold"&gt;$&lt;/span&gt; second (x&lt;span style="font-weight: bold"&gt;-&lt;/span&gt;) &lt;span style="font-weight: bold"&gt;$&lt;/span&gt; head &lt;span style="font-weight: bold"&gt;$&lt;/span&gt; filter ((&lt;span style="font-weight: bold"&gt;&amp;lt;=&lt;/span&gt;x) &lt;span style="font-weight: bold"&gt;.&lt;/span&gt; snd) numerals
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;This function is going to return either Nothing (in the base case) or Just a 
tuple of type (String, Integer), where the string is the largest roman numeral 
that's smaller than x and the int is the difference between x and the value of 
that roman numeral.
&lt;p&gt;The first thing we do is filter out the numerals larger than x; we can run 
some quick tests at the interactive console to see how this works:
&lt;p&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span style="color: #445588; font-weight: bold"&gt;Prelude&lt;/span&gt;&lt;span style="font-weight: bold"&gt;&amp;gt;&lt;/span&gt; &lt;span style="font-weight: bold"&gt;let&lt;/span&gt; numerals &lt;span style="font-weight: bold"&gt;=&lt;/span&gt; [(&lt;span style="color: #bb8844"&gt;&amp;quot;M&amp;quot;&lt;/span&gt;, &lt;span style="color: #009999"&gt;1000&lt;/span&gt;), (&lt;span style="color: #bb8844"&gt;&amp;quot;CM&amp;quot;&lt;/span&gt;, &lt;span style="color: #009999"&gt;900&lt;/span&gt;), (&lt;span style="color: #bb8844"&gt;&amp;quot;D&amp;quot;&lt;/span&gt;, &lt;span style="color: #009999"&gt;500&lt;/span&gt;)]
&lt;span style="color: #445588; font-weight: bold"&gt;Prelude&lt;/span&gt;&lt;span style="font-weight: bold"&gt;&amp;gt;&lt;/span&gt; filter ((&lt;span style="font-weight: bold"&gt;&amp;lt;=&lt;/span&gt;&lt;span style="color: #009999"&gt;900&lt;/span&gt;) &lt;span style="font-weight: bold"&gt;.&lt;/span&gt; snd) numerals
[(&lt;span style="color: #bb8844"&gt;&amp;quot;CM&amp;quot;&lt;/span&gt;,&lt;span style="color: #009999"&gt;900&lt;/span&gt;),(&lt;span style="color: #bb8844"&gt;&amp;quot;D&amp;quot;&lt;/span&gt;,&lt;span style="color: #009999"&gt;500&lt;/span&gt;)]
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;We use head to grab the largest numeral we can squeeze into the current 
value:
&lt;p&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span style="color: #445588; font-weight: bold"&gt;Prelude&lt;/span&gt;&lt;span style="font-weight: bold"&gt;&amp;gt;&lt;/span&gt; head &lt;span style="font-weight: bold"&gt;$&lt;/span&gt; filter ((&lt;span style="font-weight: bold"&gt;&amp;lt;=&lt;/span&gt;&lt;span style="color: #009999"&gt;900&lt;/span&gt;) &lt;span style="font-weight: bold"&gt;.&lt;/span&gt; snd) numerals 
(&lt;span style="color: #bb8844"&gt;&amp;quot;CM&amp;quot;&lt;/span&gt;,&lt;span style="color: #009999"&gt;900&lt;/span&gt;)
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Then we subtract the value of the roman numeral from the current value of x, 
in order to return the remainder to be operated on next:
&lt;p&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span style="color: #445588; font-weight: bold"&gt;Prelude&lt;/span&gt;&lt;span style="font-weight: bold"&gt;&amp;gt;&lt;/span&gt; &lt;span style="color: #445588; font-weight: bold"&gt;:&lt;/span&gt;m &lt;span style="color: #445588; font-weight: bold"&gt;Control&lt;/span&gt;&lt;span style="font-weight: bold"&gt;.&lt;/span&gt;&lt;span style="color: #445588; font-weight: bold"&gt;Arrow&lt;/span&gt;
&lt;span style="color: #445588; font-weight: bold"&gt;Prelude&lt;/span&gt; &lt;span style="color: #445588; font-weight: bold"&gt;Control&lt;/span&gt;&lt;span style="font-weight: bold"&gt;.&lt;/span&gt;&lt;span style="color: #445588; font-weight: bold"&gt;Arrow&lt;/span&gt;&lt;span style="font-weight: bold"&gt;&amp;gt;&lt;/span&gt; second (&lt;span style="color: #009999"&gt;900&lt;/span&gt;&lt;span style="font-weight: bold"&gt;-&lt;/span&gt;) &lt;span style="font-weight: bold"&gt;$&lt;/span&gt; head &lt;span style="font-weight: bold"&gt;$&lt;/span&gt; filter ((&lt;span style="font-weight: bold"&gt;&amp;lt;=&lt;/span&gt;&lt;span style="color: #009999"&gt;900&lt;/span&gt;) &lt;span style="font-weight: bold"&gt;.&lt;/span&gt; snd) numerals
(&lt;span style="color: #bb8844"&gt;&amp;quot;CM&amp;quot;&lt;/span&gt;,&lt;span style="color: #009999"&gt;0&lt;/span&gt;)
&lt;span style="color: #445588; font-weight: bold"&gt;Prelude&lt;/span&gt; &lt;span style="color: #445588; font-weight: bold"&gt;Control&lt;/span&gt;&lt;span style="font-weight: bold"&gt;.&lt;/span&gt;&lt;span style="color: #445588; font-weight: bold"&gt;Arrow&lt;/span&gt;&lt;span style="font-weight: bold"&gt;&amp;gt;&lt;/span&gt; second (&lt;span style="color: #009999"&gt;915&lt;/span&gt;&lt;span style="font-weight: bold"&gt;-&lt;/span&gt;) &lt;span style="font-weight: bold"&gt;$&lt;/span&gt; head &lt;span style="font-weight: bold"&gt;$&lt;/span&gt; filter ((&lt;span style="font-weight: bold"&gt;&amp;lt;=&lt;/span&gt;&lt;span style="color: #009999"&gt;915&lt;/span&gt;) &lt;span style="font-weight: bold"&gt;.&lt;/span&gt; snd) numerals
(&lt;span style="color: #bb8844"&gt;&amp;quot;CM&amp;quot;&lt;/span&gt;,&lt;span style="color: #009999"&gt;15&lt;/span&gt;)
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;And, finally, we wrap it up in a Maybe monad, so that the main function can 
handle the base case transparently:
&lt;p&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span style="color: #445588; font-weight: bold"&gt;Prelude&lt;/span&gt; &lt;span style="color: #445588; font-weight: bold"&gt;Control&lt;/span&gt;&lt;span style="font-weight: bold"&gt;.&lt;/span&gt;&lt;span style="color: #445588; font-weight: bold"&gt;Arrow&lt;/span&gt;&lt;span style="font-weight: bold"&gt;&amp;gt;&lt;/span&gt; &lt;span style="color: #445588; font-weight: bold"&gt;Just&lt;/span&gt; &lt;span style="font-weight: bold"&gt;$&lt;/span&gt; second (&lt;span style="color: #009999"&gt;915&lt;/span&gt;&lt;span style="font-weight: bold"&gt;-&lt;/span&gt;)  &lt;span style="font-weight: bold"&gt;$&lt;/span&gt; head &lt;span style="font-weight: bold"&gt;$&lt;/span&gt; 
    filter ((&lt;span style="font-weight: bold"&gt;&amp;lt;=&lt;/span&gt;&lt;span style="color: #009999"&gt;915&lt;/span&gt;) &lt;span style="font-weight: bold"&gt;.&lt;/span&gt;  snd) numerals
&lt;span style="color: #445588; font-weight: bold"&gt;Just&lt;/span&gt; (&lt;span style="color: #bb8844"&gt;&amp;quot;CM&amp;quot;&lt;/span&gt;,&lt;span style="color: #009999"&gt;15&lt;/span&gt;)
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;And now we're getting pretty close! What we have is a function that returns 
either Nothing or a tuple containing a letter to add to our roman numeral and 
the next value to operate on. All we have left is the code to drive the 
operation:
&lt;p&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span style="color: #990000; font-weight: bold"&gt;romanize&lt;/span&gt; &lt;span style="font-weight: bold"&gt;=&lt;/span&gt; concat &lt;span style="font-weight: bold"&gt;.&lt;/span&gt; unfoldr next
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;The use of unfoldr helps explain why we've wrapped next up in Maybe; here's 
its type:
&lt;p&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span style="color: #445588; font-weight: bold"&gt;Prelude&lt;/span&gt; &lt;span style="color: #445588; font-weight: bold"&gt;Control&lt;/span&gt;&lt;span style="font-weight: bold"&gt;.&lt;/span&gt;&lt;span style="color: #445588; font-weight: bold"&gt;Arrow&lt;/span&gt;&lt;span style="font-weight: bold"&gt;&amp;gt;&lt;/span&gt; &lt;span style="color: #445588; font-weight: bold"&gt;:&lt;/span&gt;m &lt;span style="color: #445588; font-weight: bold"&gt;List&lt;/span&gt;
&lt;span style="color: #445588; font-weight: bold"&gt;Prelude&lt;/span&gt; &lt;span style="color: #445588; font-weight: bold"&gt;List&lt;/span&gt;&lt;span style="font-weight: bold"&gt;&amp;gt;&lt;/span&gt; &lt;span style="color: #445588; font-weight: bold"&gt;:&lt;/span&gt;t unfoldr
&lt;span style="color: #990000; font-weight: bold"&gt;unfoldr&lt;/span&gt; &lt;span style="font-weight: bold"&gt;::&lt;/span&gt; (b &lt;span style="font-weight: bold"&gt;-&amp;gt;&lt;/span&gt; &lt;span style="color: #445588; font-weight: bold"&gt;Maybe&lt;/span&gt; (a, b)) &lt;span style="font-weight: bold"&gt;-&amp;gt;&lt;/span&gt; b &lt;span style="font-weight: bold"&gt;-&amp;gt;&lt;/span&gt; [a]
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;So we'll take a function from b -&gt; Maybe (a, b), a value of type b, and 
return a list of [a]. In our case, a = String and b = Integer.
&lt;p&gt;All unfoldr does is call the function it's given as a first argument, which 
returns a tuple or Nothing. If it's a tuple, it appends its first element to a 
list and calls the same function with the second element. If it's Nothing, it 
returns the list it's built up to this point.
&lt;p&gt;As we can see, that matches up perfectly with the "next" function we've 
already defined, and the unfoldr will build up a list of roman numeral strings:
&lt;p&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span style="color: #445588; font-weight: bold"&gt;Prelude&lt;/span&gt;&lt;span style="font-weight: bold"&gt;&amp;gt;&lt;/span&gt; &lt;span style="color: #445588; font-weight: bold"&gt;:&lt;/span&gt;m &lt;span style="color: #445588; font-weight: bold"&gt;Control&lt;/span&gt;&lt;span style="font-weight: bold"&gt;.&lt;/span&gt;&lt;span style="color: #445588; font-weight: bold"&gt;Arrow&lt;/span&gt; &lt;span style="color: #445588; font-weight: bold"&gt;List&lt;/span&gt;
&lt;span style="color: #445588; font-weight: bold"&gt;Prelude&lt;/span&gt; &lt;span style="color: #445588; font-weight: bold"&gt;Control&lt;/span&gt;&lt;span style="font-weight: bold"&gt;.&lt;/span&gt;&lt;span style="color: #445588; font-weight: bold"&gt;Arrow&lt;/span&gt; &lt;span style="color: #445588; font-weight: bold"&gt;List&lt;/span&gt;&lt;span style="font-weight: bold"&gt;&amp;gt;&lt;/span&gt; &lt;span style="font-weight: bold"&gt;let&lt;/span&gt; numerals &lt;span style="font-weight: bold"&gt;=&lt;/span&gt; [(&lt;span style="color: #bb8844"&gt;&amp;quot;X&amp;quot;&lt;/span&gt;, &lt;span style="color: #009999"&gt;10&lt;/span&gt;), (&lt;span style="color: #bb8844"&gt;&amp;quot;IX&amp;quot;&lt;/span&gt;, &lt;span style="color: #009999"&gt;9&lt;/span&gt;), (&lt;span style="color: #bb8844"&gt;&amp;quot;V&amp;quot;&lt;/span&gt;, &lt;span style="color: #009999"&gt;5&lt;/span&gt;), 
(&lt;span style="color: #bb8844"&gt;&amp;quot;IV&amp;quot;&lt;/span&gt;, &lt;span style="color: #009999"&gt;4&lt;/span&gt;), (&lt;span style="color: #bb8844"&gt;&amp;quot;I&amp;quot;&lt;/span&gt;, &lt;span style="color: #009999"&gt;1&lt;/span&gt;)]
&lt;span style="color: #445588; font-weight: bold"&gt;Prelude&lt;/span&gt; &lt;span style="color: #445588; font-weight: bold"&gt;Control&lt;/span&gt;&lt;span style="font-weight: bold"&gt;.&lt;/span&gt;&lt;span style="color: #445588; font-weight: bold"&gt;Arrow&lt;/span&gt; &lt;span style="color: #445588; font-weight: bold"&gt;List&lt;/span&gt;&lt;span style="font-weight: bold"&gt;&amp;gt;&lt;/span&gt; &lt;span style="font-weight: bold"&gt;let&lt;/span&gt; next x &lt;span style="font-weight: bold"&gt;=&lt;/span&gt; &lt;span style="font-weight: bold"&gt;if&lt;/span&gt; x&lt;span style="font-weight: bold"&gt;==&lt;/span&gt;&lt;span style="color: #009999"&gt;0&lt;/span&gt; &lt;span style="font-weight: bold"&gt;then&lt;/span&gt; &lt;span style="color: #445588; font-weight: bold"&gt;Nothing&lt;/span&gt;               
    &lt;span style="font-weight: bold"&gt;else&lt;/span&gt; &lt;span style="color: #445588; font-weight: bold"&gt;Just&lt;/span&gt; &lt;span style="font-weight: bold"&gt;$&lt;/span&gt; second (x&lt;span style="font-weight: bold"&gt;-&lt;/span&gt;) &lt;span style="font-weight: bold"&gt;$&lt;/span&gt; head &lt;span style="font-weight: bold"&gt;$&lt;/span&gt; filter ((&lt;span style="font-weight: bold"&gt;&amp;lt;=&lt;/span&gt;x) &lt;span style="font-weight: bold"&gt;.&lt;/span&gt; snd) numerals
&lt;span style="color: #445588; font-weight: bold"&gt;Prelude&lt;/span&gt; &lt;span style="color: #445588; font-weight: bold"&gt;Control&lt;/span&gt;&lt;span style="font-weight: bold"&gt;.&lt;/span&gt;&lt;span style="color: #445588; font-weight: bold"&gt;Arrow&lt;/span&gt; &lt;span style="color: #445588; font-weight: bold"&gt;List&lt;/span&gt;&lt;span style="font-weight: bold"&gt;&amp;gt;&lt;/span&gt; unfoldr next &lt;span style="color: #009999"&gt;9&lt;/span&gt;
[&lt;span style="color: #bb8844"&gt;&amp;quot;IX&amp;quot;&lt;/span&gt;]
&lt;span style="color: #445588; font-weight: bold"&gt;Prelude&lt;/span&gt; &lt;span style="color: #445588; font-weight: bold"&gt;Control&lt;/span&gt;&lt;span style="font-weight: bold"&gt;.&lt;/span&gt;&lt;span style="color: #445588; font-weight: bold"&gt;Arrow&lt;/span&gt; &lt;span style="color: #445588; font-weight: bold"&gt;List&lt;/span&gt;&lt;span style="font-weight: bold"&gt;&amp;gt;&lt;/span&gt; unfoldr next &lt;span style="color: #009999"&gt;8&lt;/span&gt;
[&lt;span style="color: #bb8844"&gt;&amp;quot;V&amp;quot;&lt;/span&gt;,&lt;span style="color: #bb8844"&gt;&amp;quot;I&amp;quot;&lt;/span&gt;,&lt;span style="color: #bb8844"&gt;&amp;quot;I&amp;quot;&lt;/span&gt;,&lt;span style="color: #bb8844"&gt;&amp;quot;I&amp;quot;&lt;/span&gt;]
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;(We had to mangle the definition of next a bit to fit into the interactive 
interpreter, but we haven't changed anything fundamental about it.)
&lt;p&gt;Finally, all we have to do is concatenate the strings into our final result:
&lt;p&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span style="color: #445588; font-weight: bold"&gt;Prelude&lt;/span&gt; &lt;span style="color: #445588; font-weight: bold"&gt;Control&lt;/span&gt;&lt;span style="font-weight: bold"&gt;.&lt;/span&gt;&lt;span style="color: #445588; font-weight: bold"&gt;Arrow&lt;/span&gt; &lt;span style="color: #445588; font-weight: bold"&gt;List&lt;/span&gt;&lt;span style="font-weight: bold"&gt;&amp;gt;&lt;/span&gt; (concat &lt;span style="font-weight: bold"&gt;.&lt;/span&gt; unfoldr next) &lt;span style="color: #009999"&gt;8&lt;/span&gt;
&lt;span style="color: #bb8844"&gt;&amp;quot;VIII&amp;quot;&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;&lt;h2&gt;Conclusion&lt;/h2&gt;
&lt;p&gt;Phew - that's an awful lot of information stuffed into a few pretty lines! I 
still have a hell of a time geting the types to match up so that I can write 
stuff like this, but that doesn't mean that I can't appreciate the beauty of 
how it all fits together. The original function presented here is tight in the 
very best sense of the word.
</summary>
		<content type="html">This bit of code for converting numbers into their Roman numeral equivalents 
was posted by &lt;a 
href="http://programming.reddit.com/info/658ys/comments/c02vm1j"&gt;geezusfreeek&lt;/a&gt; 
on reddit, and I found it so alarmingly pretty that I'm going to spend some 
time to break it down.  This exercise is largely for my own edification, but 
perhaps somebody else will learn a bit along the way. Here's the code:
&lt;p&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span style="font-weight: bold"&gt;import&lt;/span&gt; &lt;span style="color: #555555"&gt;List&lt;/span&gt;
&lt;span style="font-weight: bold"&gt;import&lt;/span&gt; &lt;span style="color: #555555"&gt;Control.Arrow&lt;/span&gt;

&lt;span style="color: #990000; font-weight: bold"&gt;romanize&lt;/span&gt; &lt;span style="font-weight: bold"&gt;=&lt;/span&gt; concat &lt;span style="font-weight: bold"&gt;.&lt;/span&gt; unfoldr next
    &lt;span style="font-weight: bold"&gt;where&lt;/span&gt; next &lt;span style="color: #009999"&gt;0&lt;/span&gt; &lt;span style="font-weight: bold"&gt;=&lt;/span&gt; &lt;span style="color: #445588; font-weight: bold"&gt;Nothing&lt;/span&gt;
          next x &lt;span style="font-weight: bold"&gt;=&lt;/span&gt; &lt;span style="color: #445588; font-weight: bold"&gt;Just&lt;/span&gt; &lt;span style="font-weight: bold"&gt;$&lt;/span&gt; second (x&lt;span style="font-weight: bold"&gt;-&lt;/span&gt;) &lt;span style="font-weight: bold"&gt;$&lt;/span&gt; head &lt;span style="font-weight: bold"&gt;$&lt;/span&gt; filter ((&lt;span style="font-weight: bold"&gt;&amp;lt;=&lt;/span&gt;x) &lt;span style="font-weight: bold"&gt;.&lt;/span&gt; snd) numerals
          numerals &lt;span style="font-weight: bold"&gt;=&lt;/span&gt; [(&lt;span style="color: #bb8844"&gt;&amp;quot;M&amp;quot;&lt;/span&gt;, &lt;span style="color: #009999"&gt;1000&lt;/span&gt;), (&lt;span style="color: #bb8844"&gt;&amp;quot;CM&amp;quot;&lt;/span&gt;, &lt;span style="color: #009999"&gt;900&lt;/span&gt;), (&lt;span style="color: #bb8844"&gt;&amp;quot;D&amp;quot;&lt;/span&gt;, &lt;span style="color: #009999"&gt;500&lt;/span&gt;), (&lt;span style="color: #bb8844"&gt;&amp;quot;CD&amp;quot;&lt;/span&gt;, &lt;span style="color: #009999"&gt;400&lt;/span&gt;),
                      (&lt;span style="color: #bb8844"&gt;&amp;quot;C&amp;quot;&lt;/span&gt;, &lt;span style="color: #009999"&gt;100&lt;/span&gt;),  (&lt;span style="color: #bb8844"&gt;&amp;quot;XC&amp;quot;&lt;/span&gt;, &lt;span style="color: #009999"&gt;90&lt;/span&gt;),  (&lt;span style="color: #bb8844"&gt;&amp;quot;L&amp;quot;&lt;/span&gt;, &lt;span style="color: #009999"&gt;50&lt;/span&gt;),  (&lt;span style="color: #bb8844"&gt;&amp;quot;XL&amp;quot;&lt;/span&gt;, &lt;span style="color: #009999"&gt;40&lt;/span&gt;),
                      (&lt;span style="color: #bb8844"&gt;&amp;quot;X&amp;quot;&lt;/span&gt;, &lt;span style="color: #009999"&gt;10&lt;/span&gt;),   (&lt;span style="color: #bb8844"&gt;&amp;quot;IX&amp;quot;&lt;/span&gt;, &lt;span style="color: #009999"&gt;9&lt;/span&gt;),   (&lt;span style="color: #bb8844"&gt;&amp;quot;V&amp;quot;&lt;/span&gt;, &lt;span style="color: #009999"&gt;5&lt;/span&gt;),   (&lt;span style="color: #bb8844"&gt;&amp;quot;IV&amp;quot;&lt;/span&gt;, &lt;span style="color: #009999"&gt;4&lt;/span&gt;),
                      (&lt;span style="color: #bb8844"&gt;&amp;quot;I&amp;quot;&lt;/span&gt;, &lt;span style="color: #009999"&gt;1&lt;/span&gt;)]
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Starting from the inside out is usually the easiest method of understanding 
blocks like this, so we'll look first at the "numerals" list. It is, simply, a 
list of tuples matching Roman numerals to their value. Importantly, it's 
ordered from largest to smallest; we'll see why shortly.&lt;/p&gt;
&lt;p&gt;The meat of this snippet comes in the "next" function:
&lt;p&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span style="color: #990000; font-weight: bold"&gt;next&lt;/span&gt; &lt;span style="color: #009999"&gt;0&lt;/span&gt; &lt;span style="font-weight: bold"&gt;=&lt;/span&gt; &lt;span style="color: #445588; font-weight: bold"&gt;Nothing&lt;/span&gt;
&lt;span style="color: #990000; font-weight: bold"&gt;next&lt;/span&gt; x &lt;span style="font-weight: bold"&gt;=&lt;/span&gt; &lt;span style="color: #445588; font-weight: bold"&gt;Just&lt;/span&gt; &lt;span style="font-weight: bold"&gt;$&lt;/span&gt; second (x&lt;span style="font-weight: bold"&gt;-&lt;/span&gt;) &lt;span style="font-weight: bold"&gt;$&lt;/span&gt; head &lt;span style="font-weight: bold"&gt;$&lt;/span&gt; filter ((&lt;span style="font-weight: bold"&gt;&amp;lt;=&lt;/span&gt;x) &lt;span style="font-weight: bold"&gt;.&lt;/span&gt; snd) numerals
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;This function is going to return either Nothing (in the base case) or Just a 
tuple of type (String, Integer), where the string is the largest roman numeral 
that's smaller than x and the int is the difference between x and the value of 
that roman numeral.
&lt;p&gt;The first thing we do is filter out the numerals larger than x; we can run 
some quick tests at the interactive console to see how this works:
&lt;p&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span style="color: #445588; font-weight: bold"&gt;Prelude&lt;/span&gt;&lt;span style="font-weight: bold"&gt;&amp;gt;&lt;/span&gt; &lt;span style="font-weight: bold"&gt;let&lt;/span&gt; numerals &lt;span style="font-weight: bold"&gt;=&lt;/span&gt; [(&lt;span style="color: #bb8844"&gt;&amp;quot;M&amp;quot;&lt;/span&gt;, &lt;span style="color: #009999"&gt;1000&lt;/span&gt;), (&lt;span style="color: #bb8844"&gt;&amp;quot;CM&amp;quot;&lt;/span&gt;, &lt;span style="color: #009999"&gt;900&lt;/span&gt;), (&lt;span style="color: #bb8844"&gt;&amp;quot;D&amp;quot;&lt;/span&gt;, &lt;span style="color: #009999"&gt;500&lt;/span&gt;)]
&lt;span style="color: #445588; font-weight: bold"&gt;Prelude&lt;/span&gt;&lt;span style="font-weight: bold"&gt;&amp;gt;&lt;/span&gt; filter ((&lt;span style="font-weight: bold"&gt;&amp;lt;=&lt;/span&gt;&lt;span style="color: #009999"&gt;900&lt;/span&gt;) &lt;span style="font-weight: bold"&gt;.&lt;/span&gt; snd) numerals
[(&lt;span style="color: #bb8844"&gt;&amp;quot;CM&amp;quot;&lt;/span&gt;,&lt;span style="color: #009999"&gt;900&lt;/span&gt;),(&lt;span style="color: #bb8844"&gt;&amp;quot;D&amp;quot;&lt;/span&gt;,&lt;span style="color: #009999"&gt;500&lt;/span&gt;)]
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;We use head to grab the largest numeral we can squeeze into the current 
value:
&lt;p&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span style="color: #445588; font-weight: bold"&gt;Prelude&lt;/span&gt;&lt;span style="font-weight: bold"&gt;&amp;gt;&lt;/span&gt; head &lt;span style="font-weight: bold"&gt;$&lt;/span&gt; filter ((&lt;span style="font-weight: bold"&gt;&amp;lt;=&lt;/span&gt;&lt;span style="color: #009999"&gt;900&lt;/span&gt;) &lt;span style="font-weight: bold"&gt;.&lt;/span&gt; snd) numerals 
(&lt;span style="color: #bb8844"&gt;&amp;quot;CM&amp;quot;&lt;/span&gt;,&lt;span style="color: #009999"&gt;900&lt;/span&gt;)
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Then we subtract the value of the roman numeral from the current value of x, 
in order to return the remainder to be operated on next:
&lt;p&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span style="color: #445588; font-weight: bold"&gt;Prelude&lt;/span&gt;&lt;span style="font-weight: bold"&gt;&amp;gt;&lt;/span&gt; &lt;span style="color: #445588; font-weight: bold"&gt;:&lt;/span&gt;m &lt;span style="color: #445588; font-weight: bold"&gt;Control&lt;/span&gt;&lt;span style="font-weight: bold"&gt;.&lt;/span&gt;&lt;span style="color: #445588; font-weight: bold"&gt;Arrow&lt;/span&gt;
&lt;span style="color: #445588; font-weight: bold"&gt;Prelude&lt;/span&gt; &lt;span style="color: #445588; font-weight: bold"&gt;Control&lt;/span&gt;&lt;span style="font-weight: bold"&gt;.&lt;/span&gt;&lt;span style="color: #445588; font-weight: bold"&gt;Arrow&lt;/span&gt;&lt;span style="font-weight: bold"&gt;&amp;gt;&lt;/span&gt; second (&lt;span style="color: #009999"&gt;900&lt;/span&gt;&lt;span style="font-weight: bold"&gt;-&lt;/span&gt;) &lt;span style="font-weight: bold"&gt;$&lt;/span&gt; head &lt;span style="font-weight: bold"&gt;$&lt;/span&gt; filter ((&lt;span style="font-weight: bold"&gt;&amp;lt;=&lt;/span&gt;&lt;span style="color: #009999"&gt;900&lt;/span&gt;) &lt;span style="font-weight: bold"&gt;.&lt;/span&gt; snd) numerals
(&lt;span style="color: #bb8844"&gt;&amp;quot;CM&amp;quot;&lt;/span&gt;,&lt;span style="color: #009999"&gt;0&lt;/span&gt;)
&lt;span style="color: #445588; font-weight: bold"&gt;Prelude&lt;/span&gt; &lt;span style="color: #445588; font-weight: bold"&gt;Control&lt;/span&gt;&lt;span style="font-weight: bold"&gt;.&lt;/span&gt;&lt;span style="color: #445588; font-weight: bold"&gt;Arrow&lt;/span&gt;&lt;span style="font-weight: bold"&gt;&amp;gt;&lt;/span&gt; second (&lt;span style="color: #009999"&gt;915&lt;/span&gt;&lt;span style="font-weight: bold"&gt;-&lt;/span&gt;) &lt;span style="font-weight: bold"&gt;$&lt;/span&gt; head &lt;span style="font-weight: bold"&gt;$&lt;/span&gt; filter ((&lt;span style="font-weight: bold"&gt;&amp;lt;=&lt;/span&gt;&lt;span style="color: #009999"&gt;915&lt;/span&gt;) &lt;span style="font-weight: bold"&gt;.&lt;/span&gt; snd) numerals
(&lt;span style="color: #bb8844"&gt;&amp;quot;CM&amp;quot;&lt;/span&gt;,&lt;span style="color: #009999"&gt;15&lt;/span&gt;)
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;And, finally, we wrap it up in a Maybe monad, so that the main function can 
handle the base case transparently:
&lt;p&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span style="color: #445588; font-weight: bold"&gt;Prelude&lt;/span&gt; &lt;span style="color: #445588; font-weight: bold"&gt;Control&lt;/span&gt;&lt;span style="font-weight: bold"&gt;.&lt;/span&gt;&lt;span style="color: #445588; font-weight: bold"&gt;Arrow&lt;/span&gt;&lt;span style="font-weight: bold"&gt;&amp;gt;&lt;/span&gt; &lt;span style="color: #445588; font-weight: bold"&gt;Just&lt;/span&gt; &lt;span style="font-weight: bold"&gt;$&lt;/span&gt; second (&lt;span style="color: #009999"&gt;915&lt;/span&gt;&lt;span style="font-weight: bold"&gt;-&lt;/span&gt;)  &lt;span style="font-weight: bold"&gt;$&lt;/span&gt; head &lt;span style="font-weight: bold"&gt;$&lt;/span&gt; 
    filter ((&lt;span style="font-weight: bold"&gt;&amp;lt;=&lt;/span&gt;&lt;span style="color: #009999"&gt;915&lt;/span&gt;) &lt;span style="font-weight: bold"&gt;.&lt;/span&gt;  snd) numerals
&lt;span style="color: #445588; font-weight: bold"&gt;Just&lt;/span&gt; (&lt;span style="color: #bb8844"&gt;&amp;quot;CM&amp;quot;&lt;/span&gt;,&lt;span style="color: #009999"&gt;15&lt;/span&gt;)
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;And now we're getting pretty close! What we have is a function that returns 
either Nothing or a tuple containing a letter to add to our roman numeral and 
the next value to operate on. All we have left is the code to drive the 
operation:
&lt;p&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span style="color: #990000; font-weight: bold"&gt;romanize&lt;/span&gt; &lt;span style="font-weight: bold"&gt;=&lt;/span&gt; concat &lt;span style="font-weight: bold"&gt;.&lt;/span&gt; unfoldr next
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;The use of unfoldr helps explain why we've wrapped next up in Maybe; here's 
its type:
&lt;p&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span style="color: #445588; font-weight: bold"&gt;Prelude&lt;/span&gt; &lt;span style="color: #445588; font-weight: bold"&gt;Control&lt;/span&gt;&lt;span style="font-weight: bold"&gt;.&lt;/span&gt;&lt;span style="color: #445588; font-weight: bold"&gt;Arrow&lt;/span&gt;&lt;span style="font-weight: bold"&gt;&amp;gt;&lt;/span&gt; &lt;span style="color: #445588; font-weight: bold"&gt;:&lt;/span&gt;m &lt;span style="color: #445588; font-weight: bold"&gt;List&lt;/span&gt;
&lt;span style="color: #445588; font-weight: bold"&gt;Prelude&lt;/span&gt; &lt;span style="color: #445588; font-weight: bold"&gt;List&lt;/span&gt;&lt;span style="font-weight: bold"&gt;&amp;gt;&lt;/span&gt; &lt;span style="color: #445588; font-weight: bold"&gt;:&lt;/span&gt;t unfoldr
&lt;span style="color: #990000; font-weight: bold"&gt;unfoldr&lt;/span&gt; &lt;span style="font-weight: bold"&gt;::&lt;/span&gt; (b &lt;span style="font-weight: bold"&gt;-&amp;gt;&lt;/span&gt; &lt;span style="color: #445588; font-weight: bold"&gt;Maybe&lt;/span&gt; (a, b)) &lt;span style="font-weight: bold"&gt;-&amp;gt;&lt;/span&gt; b &lt;span style="font-weight: bold"&gt;-&amp;gt;&lt;/span&gt; [a]
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;So we'll take a function from b -&gt; Maybe (a, b), a value of type b, and 
return a list of [a]. In our case, a = String and b = Integer.
&lt;p&gt;All unfoldr does is call the function it's given as a first argument, which 
returns a tuple or Nothing. If it's a tuple, it appends its first element to a 
list and calls the same function with the second element. If it's Nothing, it 
returns the list it's built up to this point.
&lt;p&gt;As we can see, that matches up perfectly with the "next" function we've 
already defined, and the unfoldr will build up a list of roman numeral strings:
&lt;p&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span style="color: #445588; font-weight: bold"&gt;Prelude&lt;/span&gt;&lt;span style="font-weight: bold"&gt;&amp;gt;&lt;/span&gt; &lt;span style="color: #445588; font-weight: bold"&gt;:&lt;/span&gt;m &lt;span style="color: #445588; font-weight: bold"&gt;Control&lt;/span&gt;&lt;span style="font-weight: bold"&gt;.&lt;/span&gt;&lt;span style="color: #445588; font-weight: bold"&gt;Arrow&lt;/span&gt; &lt;span style="color: #445588; font-weight: bold"&gt;List&lt;/span&gt;
&lt;span style="color: #445588; font-weight: bold"&gt;Prelude&lt;/span&gt; &lt;span style="color: #445588; font-weight: bold"&gt;Control&lt;/span&gt;&lt;span style="font-weight: bold"&gt;.&lt;/span&gt;&lt;span style="color: #445588; font-weight: bold"&gt;Arrow&lt;/span&gt; &lt;span style="color: #445588; font-weight: bold"&gt;List&lt;/span&gt;&lt;span style="font-weight: bold"&gt;&amp;gt;&lt;/span&gt; &lt;span style="font-weight: bold"&gt;let&lt;/span&gt; numerals &lt;span style="font-weight: bold"&gt;=&lt;/span&gt; [(&lt;span style="color: #bb8844"&gt;&amp;quot;X&amp;quot;&lt;/span&gt;, &lt;span style="color: #009999"&gt;10&lt;/span&gt;), (&lt;span style="color: #bb8844"&gt;&amp;quot;IX&amp;quot;&lt;/span&gt;, &lt;span style="color: #009999"&gt;9&lt;/span&gt;), (&lt;span style="color: #bb8844"&gt;&amp;quot;V&amp;quot;&lt;/span&gt;, &lt;span style="color: #009999"&gt;5&lt;/span&gt;), 
(&lt;span style="color: #bb8844"&gt;&amp;quot;IV&amp;quot;&lt;/span&gt;, &lt;span style="color: #009999"&gt;4&lt;/span&gt;), (&lt;span style="color: #bb8844"&gt;&amp;quot;I&amp;quot;&lt;/span&gt;, &lt;span style="color: #009999"&gt;1&lt;/span&gt;)]
&lt;span style="color: #445588; font-weight: bold"&gt;Prelude&lt;/span&gt; &lt;span style="color: #445588; font-weight: bold"&gt;Control&lt;/span&gt;&lt;span style="font-weight: bold"&gt;.&lt;/span&gt;&lt;span style="color: #445588; font-weight: bold"&gt;Arrow&lt;/span&gt; &lt;span style="color: #445588; font-weight: bold"&gt;List&lt;/span&gt;&lt;span style="font-weight: bold"&gt;&amp;gt;&lt;/span&gt; &lt;span style="font-weight: bold"&gt;let&lt;/span&gt; next x &lt;span style="font-weight: bold"&gt;=&lt;/span&gt; &lt;span style="font-weight: bold"&gt;if&lt;/span&gt; x&lt;span style="font-weight: bold"&gt;==&lt;/span&gt;&lt;span style="color: #009999"&gt;0&lt;/span&gt; &lt;span style="font-weight: bold"&gt;then&lt;/span&gt; &lt;span style="color: #445588; font-weight: bold"&gt;Nothing&lt;/span&gt;               
    &lt;span style="font-weight: bold"&gt;else&lt;/span&gt; &lt;span style="color: #445588; font-weight: bold"&gt;Just&lt;/span&gt; &lt;span style="font-weight: bold"&gt;$&lt;/span&gt; second (x&lt;span style="font-weight: bold"&gt;-&lt;/span&gt;) &lt;span style="font-weight: bold"&gt;$&lt;/span&gt; head &lt;span style="font-weight: bold"&gt;$&lt;/span&gt; filter ((&lt;span style="font-weight: bold"&gt;&amp;lt;=&lt;/span&gt;x) &lt;span style="font-weight: bold"&gt;.&lt;/span&gt; snd) numerals
&lt;span style="color: #445588; font-weight: bold"&gt;Prelude&lt;/span&gt; &lt;span style="color: #445588; font-weight: bold"&gt;Control&lt;/span&gt;&lt;span style="font-weight: bold"&gt;.&lt;/span&gt;&lt;span style="color: #445588; font-weight: bold"&gt;Arrow&lt;/span&gt; &lt;span style="color: #445588; font-weight: bold"&gt;List&lt;/span&gt;&lt;span style="font-weight: bold"&gt;&amp;gt;&lt;/span&gt; unfoldr next &lt;span style="color: #009999"&gt;9&lt;/span&gt;
[&lt;span style="color: #bb8844"&gt;&amp;quot;IX&amp;quot;&lt;/span&gt;]
&lt;span style="color: #445588; font-weight: bold"&gt;Prelude&lt;/span&gt; &lt;span style="color: #445588; font-weight: bold"&gt;Control&lt;/span&gt;&lt;span style="font-weight: bold"&gt;.&lt;/span&gt;&lt;span style="color: #445588; font-weight: bold"&gt;Arrow&lt;/span&gt; &lt;span style="color: #445588; font-weight: bold"&gt;List&lt;/span&gt;&lt;span style="font-weight: bold"&gt;&amp;gt;&lt;/span&gt; unfoldr next &lt;span style="color: #009999"&gt;8&lt;/span&gt;
[&lt;span style="color: #bb8844"&gt;&amp;quot;V&amp;quot;&lt;/span&gt;,&lt;span style="color: #bb8844"&gt;&amp;quot;I&amp;quot;&lt;/span&gt;,&lt;span style="color: #bb8844"&gt;&amp;quot;I&amp;quot;&lt;/span&gt;,&lt;span style="color: #bb8844"&gt;&amp;quot;I&amp;quot;&lt;/span&gt;]
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;(We had to mangle the definition of next a bit to fit into the interactive 
interpreter, but we haven't changed anything fundamental about it.)
&lt;p&gt;Finally, all we have to do is concatenate the strings into our final result:
&lt;p&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span style="color: #445588; font-weight: bold"&gt;Prelude&lt;/span&gt; &lt;span style="color: #445588; font-weight: bold"&gt;Control&lt;/span&gt;&lt;span style="font-weight: bold"&gt;.&lt;/span&gt;&lt;span style="color: #445588; font-weight: bold"&gt;Arrow&lt;/span&gt; &lt;span style="color: #445588; font-weight: bold"&gt;List&lt;/span&gt;&lt;span style="font-weight: bold"&gt;&amp;gt;&lt;/span&gt; (concat &lt;span style="font-weight: bold"&gt;.&lt;/span&gt; unfoldr next) &lt;span style="color: #009999"&gt;8&lt;/span&gt;
&lt;span style="color: #bb8844"&gt;&amp;quot;VIII&amp;quot;&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;&lt;h2&gt;Conclusion&lt;/h2&gt;
&lt;p&gt;Phew - that's an awful lot of information stuffed into a few pretty lines! I 
still have a hell of a time geting the types to match up so that I can write 
stuff like this, but that doesn't mean that I can't appreciate the beauty of 
how it all fits together. The original function presented here is tight in the 
very best sense of the word.
</content>
	</entry>
	<entry>
		<title>Why Publish CS Papers Without Code?</title>
		<link href="http://billmill.org/why_no_code.html" />	
		<id>http://billmill.org/why_no_code.html</id>
		<updated>2007-03-12T07:29:00Z</updated>
		<summary type="html">&lt;p&gt;Imagine that you read a paper analyzing "Hamlet" in great detail. Intrigued, 
you went to the bookstore to look for a copy, only to find that there were 
none. Confused, you checked the library - nothing. Finally, you went online to 
shakespeare.com, only to find a note saying that "Hamlet" was still being 
edited and would be released Any Day Now.&lt;/p&gt;
&lt;p&gt;Unfortunately, an analogous situation is the norm in the world of academic 
computer science. Graduate students and professors produce code by the 
truckload, and a majority of them produce only papers about their work. While 
this is certainly &lt;a href="http://www.cs.waikato.ac.nz/~ml/"&gt;not&lt;/a&gt; &lt;a 
href="http://www.bluej.org/"&gt;always&lt;/a&gt; &lt;a 
href="https://www.drproject.org/"&gt;the&lt;/a&gt; &lt;a 
href="http://www.haskell.org/ghc/"&gt;case&lt;/a&gt;, it was difficult for me to even 
find these examples of academic source code. In all four cases, it has proven 
very useful to programmers outside of academia.&lt;/p&gt;
&lt;h1&gt;Life, not Math&lt;/h1&gt;
&lt;p&gt;The fact is, computer science research is more like biology research than it 
is like mathematical research. For an experiment to be valid, it should be 
repeatable. If you're publishing analyses of programs without publishing the 
code that was analyzed, how can the community possibly verify what you 
claim?&lt;/p&gt;
&lt;p&gt;Bugs are endemic to source code everywhere, and there is no reason to 
believe that academic code is any different. All of the analysis in the world 
is irrelevant if the program you are analyzing has a subtle bug embedded in it.  
We, computer scientists, should expect and demand that published, well tested 
code be made available with every paper which claims to analyze or draw 
conclusions from a program of any significant size.&lt;/p&gt;
&lt;h1&gt;A Problem of Environment?&lt;/h1&gt;
&lt;p&gt;At the moment, there is just no easy way to do this. Where the open 
source world has &lt;a href="http://sf.net"&gt;SourceForge&lt;/a&gt; and other project 
hosting sites, there is no similar environment where academic papers can live 
alongside the code they reference. Instead, computer science researchers are 
encouraged to publish papers in traditional, copyright-locked, academic 
journals. These journals are not prepared to handle large volumes of code, nor 
should they be. Computer science research was made for the web, and there 
should be a home for it on the web.&lt;/p&gt;
&lt;p&gt;It is intimidating for a harried academic that just wants to get work done, 
and advance in his field, to have to set up the host of tools required to share 
code effectively. If there were a SourceForge-for-academics site where they 
could simply register their paper, drop in the source code, and have a project 
ready made for them, it would be much more likely that they would participate.  
If such a project were to gain steam, the network effect would make it an 
invaluable resource for academic and industry programmers alike. Collaboration 
and open code sharing would lead to much more rapid progress in the field, and 
hopefully encourage the greater rigor that other fields require of their 
practitioners.&lt;/p&gt;
&lt;h1&gt;Two Different Worlds&lt;/h1&gt;
&lt;p&gt;Right now, academics and open-source programmers live largely in two 
separate, often parallel, worlds. Where they do collide, as they do in the 
Haskell language, there is often extremely interesting work being produced.  
Each brings a different, interesting, viewpoint to the table, and greater 
coordination between the two would have nearly universal benefits for 
programmers of every stripe.&lt;/p&gt;
&lt;p&gt;So free the code! If you're an academic programmer, consider publishing the 
code that you have, regardless of what you may think of it. Consider asking the 
journal that you publish in to retain copyright over your work. If you're an 
open source programmer, look for some work in a field that interests you, and 
email the author if he hasn't released his code. Ask him an interesting 
question, and convince him that his code would be useful. If you're both, tell 
the world your ideas for how we can all work better together.&lt;/p&gt;
&lt;h1&gt;Update:&lt;/h1&gt;
&lt;p&gt;I've been contacted already by two scientists who care about the 
reproducibility of programs. First, &lt;a 
href="http://www.cs.mu.oz.au/~gavinb/index.php"&gt;Gavin Baker&lt;/a&gt; wrote to tell 
me about the &lt;a href="http://itk.org"&gt;insight toolkit&lt;/a&gt;, which "is a 
cross-platform open-source image processing toolkit for performing registration 
and segmentation" that attempts to provide reference implementations of 
published algorithms. He also pointed me towards &lt;a 
href="http://www.insight-journal.org/"&gt;The Insight Journal&lt;/a&gt;, which allows 
authors to publish open articles which are automatically verified with CMake.  
This is exactly the type of thing I was hoping to hear about.&lt;/p&gt;
&lt;p&gt;Only a few minutes later, "I. Vlad" wrote to tell me that computational 
geophysicists have a similar system called &lt;a 
href="http://rsf.sourceforge.net/"&gt;Madagascar&lt;/a&gt;, which uses SCons to provide 
automated verification of results. Furthermore, they encourage the use of open 
data sets from &lt;a href="http://software.seg.org/"&gt;the website&lt;/a&gt; for the 
Society of Exploration Geophysicists.&lt;/p&gt;
&lt;p&gt;Good to hear that these scientists are out there making stuff happen, while 
I sit here on my duff.&lt;/p&gt;
&lt;h1&gt;Update 2&lt;/h1&gt;
&lt;p&gt;Made a correction to the update. (Made it clear that the Madagascar project 
did not set up the SEG site - sloppy writing on my part).&lt;/p&gt;
</summary>
		<content type="html">&lt;p&gt;Imagine that you read a paper analyzing "Hamlet" in great detail. Intrigued, 
you went to the bookstore to look for a copy, only to find that there were 
none. Confused, you checked the library - nothing. Finally, you went online to 
shakespeare.com, only to find a note saying that "Hamlet" was still being 
edited and would be released Any Day Now.&lt;/p&gt;
&lt;p&gt;Unfortunately, an analogous situation is the norm in the world of academic 
computer science. Graduate students and professors produce code by the 
truckload, and a majority of them produce only papers about their work. While 
this is certainly &lt;a href="http://www.cs.waikato.ac.nz/~ml/"&gt;not&lt;/a&gt; &lt;a 
href="http://www.bluej.org/"&gt;always&lt;/a&gt; &lt;a 
href="https://www.drproject.org/"&gt;the&lt;/a&gt; &lt;a 
href="http://www.haskell.org/ghc/"&gt;case&lt;/a&gt;, it was difficult for me to even 
find these examples of academic source code. In all four cases, it has proven 
very useful to programmers outside of academia.&lt;/p&gt;
&lt;h1&gt;Life, not Math&lt;/h1&gt;
&lt;p&gt;The fact is, computer science research is more like biology research than it 
is like mathematical research. For an experiment to be valid, it should be 
repeatable. If you're publishing analyses of programs without publishing the 
code that was analyzed, how can the community possibly verify what you 
claim?&lt;/p&gt;
&lt;p&gt;Bugs are endemic to source code everywhere, and there is no reason to 
believe that academic code is any different. All of the analysis in the world 
is irrelevant if the program you are analyzing has a subtle bug embedded in it.  
We, computer scientists, should expect and demand that published, well tested 
code be made available with every paper which claims to analyze or draw 
conclusions from a program of any significant size.&lt;/p&gt;
&lt;h1&gt;A Problem of Environment?&lt;/h1&gt;
&lt;p&gt;At the moment, there is just no easy way to do this. Where the open 
source world has &lt;a href="http://sf.net"&gt;SourceForge&lt;/a&gt; and other project 
hosting sites, there is no similar environment where academic papers can live 
alongside the code they reference. Instead, computer science researchers are 
encouraged to publish papers in traditional, copyright-locked, academic 
journals. These journals are not prepared to handle large volumes of code, nor 
should they be. Computer science research was made for the web, and there 
should be a home for it on the web.&lt;/p&gt;
&lt;p&gt;It is intimidating for a harried academic that just wants to get work done, 
and advance in his field, to have to set up the host of tools required to share 
code effectively. If there were a SourceForge-for-academics site where they 
could simply register their paper, drop in the source code, and have a project 
ready made for them, it would be much more likely that they would participate.  
If such a project were to gain steam, the network effect would make it an 
invaluable resource for academic and industry programmers alike. Collaboration 
and open code sharing would lead to much more rapid progress in the field, and 
hopefully encourage the greater rigor that other fields require of their 
practitioners.&lt;/p&gt;
&lt;h1&gt;Two Different Worlds&lt;/h1&gt;
&lt;p&gt;Right now, academics and open-source programmers live largely in two 
separate, often parallel, worlds. Where they do collide, as they do in the 
Haskell language, there is often extremely interesting work being produced.  
Each brings a different, interesting, viewpoint to the table, and greater 
coordination between the two would have nearly universal benefits for 
programmers of every stripe.&lt;/p&gt;
&lt;p&gt;So free the code! If you're an academic programmer, consider publishing the 
code that you have, regardless of what you may think of it. Consider asking the 
journal that you publish in to retain copyright over your work. If you're an 
open source programmer, look for some work in a field that interests you, and 
email the author if he hasn't released his code. Ask him an interesting 
question, and convince him that his code would be useful. If you're both, tell 
the world your ideas for how we can all work better together.&lt;/p&gt;
&lt;h1&gt;Update:&lt;/h1&gt;
&lt;p&gt;I've been contacted already by two scientists who care about the 
reproducibility of programs. First, &lt;a 
href="http://www.cs.mu.oz.au/~gavinb/index.php"&gt;Gavin Baker&lt;/a&gt; wrote to tell 
me about the &lt;a href="http://itk.org"&gt;insight toolkit&lt;/a&gt;, which "is a 
cross-platform open-source image processing toolkit for performing registration 
and segmentation" that attempts to provide reference implementations of 
published algorithms. He also pointed me towards &lt;a 
href="http://www.insight-journal.org/"&gt;The Insight Journal&lt;/a&gt;, which allows 
authors to publish open articles which are automatically verified with CMake.  
This is exactly the type of thing I was hoping to hear about.&lt;/p&gt;
&lt;p&gt;Only a few minutes later, "I. Vlad" wrote to tell me that computational 
geophysicists have a similar system called &lt;a 
href="http://rsf.sourceforge.net/"&gt;Madagascar&lt;/a&gt;, which uses SCons to provide 
automated verification of results. Furthermore, they encourage the use of open 
data sets from &lt;a href="http://software.seg.org/"&gt;the website&lt;/a&gt; for the 
Society of Exploration Geophysicists.&lt;/p&gt;
&lt;p&gt;Good to hear that these scientists are out there making stuff happen, while 
I sit here on my duff.&lt;/p&gt;
&lt;h1&gt;Update 2&lt;/h1&gt;
&lt;p&gt;Made a correction to the update. (Made it clear that the Madagascar project 
did not set up the SEG site - sloppy writing on my part).&lt;/p&gt;
</content>
	</entry>
</feed>
