<?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-02-16T17:45:47Z</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>DNA on Programming</title>
		<link href="http://billmill.org/dna.html" />	
		<id>http://billmill.org/dna.html</id>
		<updated>2008-02-16T17:45:47Z</updated>
		<summary type="html">&lt;blockquote&gt;"Well, what we called a computer in 1977 was really a kind of electric abacus, but..."&lt;p&gt;
"Oh, now, don't underestimate the abacus," said Reg. "In skilled hands it's a very sophisticated calculating device. Furthermore it requires no power, can be made with any materials you have to hand, and never goes bing in the middle of an important piece of work."&lt;p&gt;
"So an electric one would be particularly pointless," said Richard.&lt;p&gt;
"True enough," conceded Reg.&lt;p&gt;
"There really wasn't a lot this machine could do that you couldn't do yourself in half the time with a lot less trouble," said Richard, "but it was, on the other hand, very good at being a slow and dim-witted pupil."&lt;p&gt;
Reg looked at him quizzically.&lt;p&gt;
"I had no idea they were in such short supply," he said. "I could hit a dozen of them with a bread roll from where I'm sitting."&lt;p&gt;
"I'm sure. But look at it this way. What really is the point of trying to teach anything to anybody?"&lt;p&gt;
This question seemed to provoke a murmur of sympathetic approval from up and down the table. &lt;p&gt;
    Richard continued, "What I mean is that if you really want to understand something, the best way is to try and explain it to someone else. That forces you to sort it out in your own mind. And the more slow and dim-witted your pupil, the more you have to break things down into more and more simple ideas. And that's really the essence of programming. By the time you've sorted out a complicated idea into little steps that even a stupid machine can deal with, you've certainly learned something about it yourself. The teacher usually learns more than the pupil. Isn't that true?"&lt;p&gt;
    "It would be hard to learn much less than my pupils," came a low growl from somewhere on the table, "without undergoing a pre-frontal lobotomy."&lt;p&gt;
    "So I used to spend days struggling to write essays on this 16K machine that would have taken a couple of hours on a typewriter, but what was fascinating to me was the process of trying to explain to the machine what it was I wanted it to do. I virtually wrote my own word processor in BASIC. A simple search and replace routine would take about three hours."&lt;p&gt;
    "I forget, did you ever get any essays done at all?"&lt;p&gt;
    "Well, not as such. No actual essays, but the reasons why not were absolutely fascinating. For instance, I discovered that..."&lt;p&gt;
    He broke off, laughing at himself.&lt;/blockquote&gt;
-&lt;a href="http://www.amazon.com/Dirk-Gentlys-Holistic-Detective-Agency/dp/0671746723"&gt;DNA&lt;/a&gt;
</summary>
		<content type="html">&lt;blockquote&gt;"Well, what we called a computer in 1977 was really a kind of electric abacus, but..."&lt;p&gt;
"Oh, now, don't underestimate the abacus," said Reg. "In skilled hands it's a very sophisticated calculating device. Furthermore it requires no power, can be made with any materials you have to hand, and never goes bing in the middle of an important piece of work."&lt;p&gt;
"So an electric one would be particularly pointless," said Richard.&lt;p&gt;
"True enough," conceded Reg.&lt;p&gt;
"There really wasn't a lot this machine could do that you couldn't do yourself in half the time with a lot less trouble," said Richard, "but it was, on the other hand, very good at being a slow and dim-witted pupil."&lt;p&gt;
Reg looked at him quizzically.&lt;p&gt;
"I had no idea they were in such short supply," he said. "I could hit a dozen of them with a bread roll from where I'm sitting."&lt;p&gt;
"I'm sure. But look at it this way. What really is the point of trying to teach anything to anybody?"&lt;p&gt;
This question seemed to provoke a murmur of sympathetic approval from up and down the table. &lt;p&gt;
    Richard continued, "What I mean is that if you really want to understand something, the best way is to try and explain it to someone else. That forces you to sort it out in your own mind. And the more slow and dim-witted your pupil, the more you have to break things down into more and more simple ideas. And that's really the essence of programming. By the time you've sorted out a complicated idea into little steps that even a stupid machine can deal with, you've certainly learned something about it yourself. The teacher usually learns more than the pupil. Isn't that true?"&lt;p&gt;
    "It would be hard to learn much less than my pupils," came a low growl from somewhere on the table, "without undergoing a pre-frontal lobotomy."&lt;p&gt;
    "So I used to spend days struggling to write essays on this 16K machine that would have taken a couple of hours on a typewriter, but what was fascinating to me was the process of trying to explain to the machine what it was I wanted it to do. I virtually wrote my own word processor in BASIC. A simple search and replace routine would take about three hours."&lt;p&gt;
    "I forget, did you ever get any essays done at all?"&lt;p&gt;
    "Well, not as such. No actual essays, but the reasons why not were absolutely fascinating. For instance, I discovered that..."&lt;p&gt;
    He broke off, laughing at himself.&lt;/blockquote&gt;
-&lt;a href="http://www.amazon.com/Dirk-Gentlys-Holistic-Detective-Agency/dp/0671746723"&gt;DNA&lt;/a&gt;
</content>
	</entry>
	<entry>
		<title>Functional Roman Numerals in Python</title>
		<link href="http://billmill.org/python_roman.html" />	
		<id>http://billmill.org/python_roman.html</id>
		<updated>2008-01-12T17:52:00Z</updated>
		<summary type="html">Just as a quck note, I thought I'd post the cleanest python I could come up 
with to solve the &lt;a href="http://billmill.org/roman.html"&gt;roman numerals&lt;/a&gt; 
problem I discussed earlier. It tries to use a functional style while actually 
avoiding recursion. To do so, I wrote an iterative python unfold:
&lt;p&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span style="font-weight: bold"&gt;def&lt;/span&gt; &lt;span style="color: #990000; font-weight: bold"&gt;unfold&lt;/span&gt;(f, x):
    res &lt;span style="font-weight: bold"&gt;=&lt;/span&gt; []                       
    &lt;span style="font-weight: bold"&gt;while&lt;/span&gt; &lt;span style="color: #009999"&gt;1&lt;/span&gt;:
        &lt;span style="font-weight: bold"&gt;try&lt;/span&gt;:
            w, x &lt;span style="font-weight: bold"&gt;=&lt;/span&gt; f(x)
            res&lt;span style="font-weight: bold"&gt;.&lt;/span&gt;append(w)
        &lt;span style="font-weight: bold"&gt;except&lt;/span&gt; &lt;span style="color: #990000; font-weight: bold"&gt;TypeError&lt;/span&gt;:
            &lt;span style="font-weight: bold"&gt;return&lt;/span&gt; res
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;And then the answer becomes:
&lt;p&gt;&lt;div class="highlight"&gt;&lt;pre&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: #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;span style="font-weight: bold"&gt;def&lt;/span&gt; &lt;span style="color: #990000; font-weight: bold"&gt;next&lt;/span&gt;(x):
    &lt;span style="font-weight: bold"&gt;for&lt;/span&gt; n &lt;span style="font-weight: bold"&gt;in&lt;/span&gt; numerals:
        &lt;span style="font-weight: bold"&gt;if&lt;/span&gt; n[&lt;span style="color: #009999"&gt;1&lt;/span&gt;] &lt;span style="font-weight: bold"&gt;&amp;lt;=&lt;/span&gt; x: &lt;span style="font-weight: bold"&gt;return&lt;/span&gt; (n[&lt;span style="color: #009999"&gt;0&lt;/span&gt;], x&lt;span style="font-weight: bold"&gt;-&lt;/span&gt;n[&lt;span style="color: #009999"&gt;1&lt;/span&gt;])

&lt;span style="font-weight: bold"&gt;def&lt;/span&gt; &lt;span style="color: #990000; font-weight: bold"&gt;romanize&lt;/span&gt;(n):
    &lt;span style="font-weight: bold"&gt;return&lt;/span&gt; &lt;span style="color: #bb8844"&gt;&amp;quot;&amp;quot;&lt;/span&gt;&lt;span style="font-weight: bold"&gt;.&lt;/span&gt;join(unfold(next, n))
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Compare to the haskell I posted before:
&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;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;The "where" idiom allows you to group helper functions and constants 
underneath the main function, and the unimportance of function order means you 
can highlight the high-level logic. The haskell code is much shorter and 
tighter than the python.
&lt;p&gt;Having powerful iterative functions like unfoldr in the standard library is 
another clear win for Haskell; it took me more lines to define unfold than it 
did to define both next() and romanize(). (By the by, some googling failed to 
turn up a previous python implementation of unfold(); I think this code gets a 
lot uglier without it. I also don't see any obvious way to do it with 
itertools.)
&lt;p&gt;On the other hand, I find the simplicity of the python next() appealing, 
with its constructive instead of declarative approach. It's a less generic 
solution that's intuitively simpler (for me, still an imperative thinker).  
&lt;p&gt;You could match the haskell more exactly:
&lt;p&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span style="font-weight: bold"&gt;from&lt;/span&gt; &lt;span style="color: #555555"&gt;itertools&lt;/span&gt; &lt;span style="font-weight: bold"&gt;import&lt;/span&gt; ifilter

&lt;span style="font-weight: bold"&gt;def&lt;/span&gt; &lt;span style="color: #990000; font-weight: bold"&gt;second&lt;/span&gt;(f, (a, b)): &lt;span style="font-weight: bold"&gt;return&lt;/span&gt; (a, f(b))

&lt;span style="font-weight: bold"&gt;def&lt;/span&gt; &lt;span style="color: #990000; font-weight: bold"&gt;next&lt;/span&gt;(x):
    &lt;span style="font-weight: bold"&gt;return&lt;/span&gt; second(&lt;span style="font-weight: bold"&gt;lambda&lt;/span&gt; a: x&lt;span style="font-weight: bold"&gt;-&lt;/span&gt;a, ifilter(&lt;span style="font-weight: bold"&gt;lambda&lt;/span&gt; (y, z): z &lt;span style="font-weight: bold"&gt;&amp;lt;=&lt;/span&gt; x, numerals)&lt;span style="font-weight: bold"&gt;.&lt;/span&gt;next()
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;but the result is pretty ugly. The inability to compose functions compactly
results in a lot of boilerplate, and in having to pick a lot of meaningless 
variable names that obscure what's going on. We could move the lambdas out of
the call and give them names:
&lt;p&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span style="font-weight: bold"&gt;def&lt;/span&gt; &lt;span style="color: #990000; font-weight: bold"&gt;next&lt;/span&gt;(x):
    subx &lt;span style="font-weight: bold"&gt;=&lt;/span&gt; &lt;span style="font-weight: bold"&gt;lambda&lt;/span&gt; a: x&lt;span style="font-weight: bold"&gt;-&lt;/span&gt;a
    ltx &lt;span style="font-weight: bold"&gt;=&lt;/span&gt; &lt;span style="font-weight: bold"&gt;lambda&lt;/span&gt; (y, z): z &lt;span style="font-weight: bold"&gt;&amp;lt;=&lt;/span&gt; x

    &lt;span style="font-weight: bold"&gt;return&lt;/span&gt; second(subx, ifilter(ltx, numerals)&lt;span style="font-weight: bold"&gt;.&lt;/span&gt;next())
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;And it's a little better, but I think we're now pretty far from idiomatic 
python.
&lt;p&gt;&lt;h2&gt;Conclusion&lt;/h2&gt;
&lt;p&gt;The python translation of the haskell isn't bad, but I do think it loses
something. The unfold() trick works really well, and translates easily into
an imperative, pythonic implementation; I'll look for ways to use it in the 
future. And, finally, I'm pretty jealous of Haskell's function combination
abilities.
&lt;p&gt;&lt;h2&gt;Updates&lt;/h2&gt;
&lt;p&gt;In the &lt;a href="http://programming.reddit.com/info/65bpf/comments/"&gt;comments&lt;/a&gt;
at reddit, nostrademons posts a nicer unfold function:
&lt;p&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span style="font-weight: bold"&gt;def&lt;/span&gt; &lt;span style="color: #990000; font-weight: bold"&gt;unfold&lt;/span&gt;(f, x):
    &lt;span style="font-weight: bold"&gt;while&lt;/span&gt; &lt;span style="color: #999999"&gt;True&lt;/span&gt;:
        w, x &lt;span style="font-weight: bold"&gt;=&lt;/span&gt; f(x)
        &lt;span style="font-weight: bold"&gt;yield&lt;/span&gt; w
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;And Kay Schluehr prefers the iterative solution:
&lt;p&gt;&lt;div class="highlight"&gt;&lt;pre&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: #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;span style="font-weight: bold"&gt;def&lt;/span&gt; &lt;span style="color: #990000; font-weight: bold"&gt;romanize&lt;/span&gt;(n):
    roman &lt;span style="font-weight: bold"&gt;=&lt;/span&gt; []
    &lt;span style="font-weight: bold"&gt;for&lt;/span&gt; ltr, num &lt;span style="font-weight: bold"&gt;in&lt;/span&gt; numerals:
        (k,n) &lt;span style="font-weight: bold"&gt;=&lt;/span&gt; &lt;span style="color: #999999"&gt;divmod&lt;/span&gt;(n, num)
        roman&lt;span style="font-weight: bold"&gt;.&lt;/span&gt;append(ltr&lt;span style="font-weight: bold"&gt;*&lt;/span&gt;k)
    &lt;span style="font-weight: bold"&gt;return&lt;/span&gt; &lt;span style="color: #bb8844"&gt;&amp;quot;&amp;quot;&lt;/span&gt;&lt;span style="font-weight: bold"&gt;.&lt;/span&gt;join(roman)
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;David Pollak contributes a Scala unfold and romanize &lt;a
href="http://scala-blogs.org/2008/01/roman-numerals-in-scala.html"&gt;at
his blog&lt;/a&gt;.
</summary>
		<content type="html">Just as a quck note, I thought I'd post the cleanest python I could come up 
with to solve the &lt;a href="http://billmill.org/roman.html"&gt;roman numerals&lt;/a&gt; 
problem I discussed earlier. It tries to use a functional style while actually 
avoiding recursion. To do so, I wrote an iterative python unfold:
&lt;p&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span style="font-weight: bold"&gt;def&lt;/span&gt; &lt;span style="color: #990000; font-weight: bold"&gt;unfold&lt;/span&gt;(f, x):
    res &lt;span style="font-weight: bold"&gt;=&lt;/span&gt; []                       
    &lt;span style="font-weight: bold"&gt;while&lt;/span&gt; &lt;span style="color: #009999"&gt;1&lt;/span&gt;:
        &lt;span style="font-weight: bold"&gt;try&lt;/span&gt;:
            w, x &lt;span style="font-weight: bold"&gt;=&lt;/span&gt; f(x)
            res&lt;span style="font-weight: bold"&gt;.&lt;/span&gt;append(w)
        &lt;span style="font-weight: bold"&gt;except&lt;/span&gt; &lt;span style="color: #990000; font-weight: bold"&gt;TypeError&lt;/span&gt;:
            &lt;span style="font-weight: bold"&gt;return&lt;/span&gt; res
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;And then the answer becomes:
&lt;p&gt;&lt;div class="highlight"&gt;&lt;pre&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: #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;span style="font-weight: bold"&gt;def&lt;/span&gt; &lt;span style="color: #990000; font-weight: bold"&gt;next&lt;/span&gt;(x):
    &lt;span style="font-weight: bold"&gt;for&lt;/span&gt; n &lt;span style="font-weight: bold"&gt;in&lt;/span&gt; numerals:
        &lt;span style="font-weight: bold"&gt;if&lt;/span&gt; n[&lt;span style="color: #009999"&gt;1&lt;/span&gt;] &lt;span style="font-weight: bold"&gt;&amp;lt;=&lt;/span&gt; x: &lt;span style="font-weight: bold"&gt;return&lt;/span&gt; (n[&lt;span style="color: #009999"&gt;0&lt;/span&gt;], x&lt;span style="font-weight: bold"&gt;-&lt;/span&gt;n[&lt;span style="color: #009999"&gt;1&lt;/span&gt;])

&lt;span style="font-weight: bold"&gt;def&lt;/span&gt; &lt;span style="color: #990000; font-weight: bold"&gt;romanize&lt;/span&gt;(n):
    &lt;span style="font-weight: bold"&gt;return&lt;/span&gt; &lt;span style="color: #bb8844"&gt;&amp;quot;&amp;quot;&lt;/span&gt;&lt;span style="font-weight: bold"&gt;.&lt;/span&gt;join(unfold(next, n))
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Compare to the haskell I posted before:
&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;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;The "where" idiom allows you to group helper functions and constants 
underneath the main function, and the unimportance of function order means you 
can highlight the high-level logic. The haskell code is much shorter and 
tighter than the python.
&lt;p&gt;Having powerful iterative functions like unfoldr in the standard library is 
another clear win for Haskell; it took me more lines to define unfold than it 
did to define both next() and romanize(). (By the by, some googling failed to 
turn up a previous python implementation of unfold(); I think this code gets a 
lot uglier without it. I also don't see any obvious way to do it with 
itertools.)
&lt;p&gt;On the other hand, I find the simplicity of the python next() appealing, 
with its constructive instead of declarative approach. It's a less generic 
solution that's intuitively simpler (for me, still an imperative thinker).  
&lt;p&gt;You could match the haskell more exactly:
&lt;p&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span style="font-weight: bold"&gt;from&lt;/span&gt; &lt;span style="color: #555555"&gt;itertools&lt;/span&gt; &lt;span style="font-weight: bold"&gt;import&lt;/span&gt; ifilter

&lt;span style="font-weight: bold"&gt;def&lt;/span&gt; &lt;span style="color: #990000; font-weight: bold"&gt;second&lt;/span&gt;(f, (a, b)): &lt;span style="font-weight: bold"&gt;return&lt;/span&gt; (a, f(b))

&lt;span style="font-weight: bold"&gt;def&lt;/span&gt; &lt;span style="color: #990000; font-weight: bold"&gt;next&lt;/span&gt;(x):
    &lt;span style="font-weight: bold"&gt;return&lt;/span&gt; second(&lt;span style="font-weight: bold"&gt;lambda&lt;/span&gt; a: x&lt;span style="font-weight: bold"&gt;-&lt;/span&gt;a, ifilter(&lt;span style="font-weight: bold"&gt;lambda&lt;/span&gt; (y, z): z &lt;span style="font-weight: bold"&gt;&amp;lt;=&lt;/span&gt; x, numerals)&lt;span style="font-weight: bold"&gt;.&lt;/span&gt;next()
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;but the result is pretty ugly. The inability to compose functions compactly
results in a lot of boilerplate, and in having to pick a lot of meaningless 
variable names that obscure what's going on. We could move the lambdas out of
the call and give them names:
&lt;p&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span style="font-weight: bold"&gt;def&lt;/span&gt; &lt;span style="color: #990000; font-weight: bold"&gt;next&lt;/span&gt;(x):
    subx &lt;span style="font-weight: bold"&gt;=&lt;/span&gt; &lt;span style="font-weight: bold"&gt;lambda&lt;/span&gt; a: x&lt;span style="font-weight: bold"&gt;-&lt;/span&gt;a
    ltx &lt;span style="font-weight: bold"&gt;=&lt;/span&gt; &lt;span style="font-weight: bold"&gt;lambda&lt;/span&gt; (y, z): z &lt;span style="font-weight: bold"&gt;&amp;lt;=&lt;/span&gt; x

    &lt;span style="font-weight: bold"&gt;return&lt;/span&gt; second(subx, ifilter(ltx, numerals)&lt;span style="font-weight: bold"&gt;.&lt;/span&gt;next())
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;And it's a little better, but I think we're now pretty far from idiomatic 
python.
&lt;p&gt;&lt;h2&gt;Conclusion&lt;/h2&gt;
&lt;p&gt;The python translation of the haskell isn't bad, but I do think it loses
something. The unfold() trick works really well, and translates easily into
an imperative, pythonic implementation; I'll look for ways to use it in the 
future. And, finally, I'm pretty jealous of Haskell's function combination
abilities.
&lt;p&gt;&lt;h2&gt;Updates&lt;/h2&gt;
&lt;p&gt;In the &lt;a href="http://programming.reddit.com/info/65bpf/comments/"&gt;comments&lt;/a&gt;
at reddit, nostrademons posts a nicer unfold function:
&lt;p&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span style="font-weight: bold"&gt;def&lt;/span&gt; &lt;span style="color: #990000; font-weight: bold"&gt;unfold&lt;/span&gt;(f, x):
    &lt;span style="font-weight: bold"&gt;while&lt;/span&gt; &lt;span style="color: #999999"&gt;True&lt;/span&gt;:
        w, x &lt;span style="font-weight: bold"&gt;=&lt;/span&gt; f(x)
        &lt;span style="font-weight: bold"&gt;yield&lt;/span&gt; w
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;And Kay Schluehr prefers the iterative solution:
&lt;p&gt;&lt;div class="highlight"&gt;&lt;pre&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: #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;span style="font-weight: bold"&gt;def&lt;/span&gt; &lt;span style="color: #990000; font-weight: bold"&gt;romanize&lt;/span&gt;(n):
    roman &lt;span style="font-weight: bold"&gt;=&lt;/span&gt; []
    &lt;span style="font-weight: bold"&gt;for&lt;/span&gt; ltr, num &lt;span style="font-weight: bold"&gt;in&lt;/span&gt; numerals:
        (k,n) &lt;span style="font-weight: bold"&gt;=&lt;/span&gt; &lt;span style="color: #999999"&gt;divmod&lt;/span&gt;(n, num)
        roman&lt;span style="font-weight: bold"&gt;.&lt;/span&gt;append(ltr&lt;span style="font-weight: bold"&gt;*&lt;/span&gt;k)
    &lt;span style="font-weight: bold"&gt;return&lt;/span&gt; &lt;span style="color: #bb8844"&gt;&amp;quot;&amp;quot;&lt;/span&gt;&lt;span style="font-weight: bold"&gt;.&lt;/span&gt;join(roman)
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;David Pollak contributes a Scala unfold and romanize &lt;a
href="http://scala-blogs.org/2008/01/roman-numerals-in-scala.html"&gt;at
his blog&lt;/a&gt;.
</content>
	</entry>
	<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>Iterating Over Database Results in C#</title>
		<link href="http://billmill.org/iterate_over_database.html" />	
		<id>http://billmill.org/iterate_over_database.html</id>
		<updated>2007-12-17T01:13:00Z</updated>
		<summary type="html">&lt;p&gt;At my job, we use what is essentially a custom C# ORM. Soon after I arrived, 
we adopted this idiom to pull a DB connection from the pool and run a query:
&lt;div class="highlight"&gt;&lt;pre&gt; &lt;span style="font-weight: bold"&gt;class&lt;/span&gt; &lt;span style="color: #445588; font-weight: bold"&gt;Something&lt;/span&gt;
&lt;span style="font-weight: bold"&gt;{&lt;/span&gt;
    &lt;span style="font-weight: bold"&gt;public&lt;/span&gt; &lt;span style="color: #445588; font-weight: bold"&gt;int&lt;/span&gt; &lt;span style="color: #990000; font-weight: bold"&gt;ourIdiom&lt;/span&gt;(&lt;span style="color: #445588; font-weight: bold"&gt;long&lt;/span&gt; identifier)
    &lt;span style="font-weight: bold"&gt;{&lt;/span&gt;
        &lt;span style="font-weight: bold"&gt;using&lt;/span&gt; (DBConnection db = &lt;span style="font-weight: bold"&gt;new&lt;/span&gt; DBConnection())
        &lt;span style="font-weight: bold"&gt;{&lt;/span&gt;
            &lt;span style="font-weight: bold"&gt;using&lt;/span&gt; (IDataReader rec = db.execQuery(&lt;span style="color: #bb8844"&gt;@&amp;quot;&lt;/span&gt;
&lt;span style="color: #bb8844"&gt;                SELECT some, rows&lt;/span&gt;
&lt;span style="color: #bb8844"&gt;                FROM  Table1 t1, Table2 t2&lt;/span&gt;
&lt;span style="color: #bb8844"&gt;                WHERE t1.t2id = t2.id&lt;/span&gt;
&lt;span style="color: #bb8844"&gt;                AND   t1.id = ?&amp;quot;&lt;/span&gt;,
                identifier))
            &lt;span style="font-weight: bold"&gt;{&lt;/span&gt;
                &lt;span style="font-weight: bold"&gt;while&lt;/span&gt; (rec.Read())
                    doSomething();
                &lt;span style="font-weight: bold"&gt;return&lt;/span&gt; &lt;span style="color: #009999"&gt;1&lt;/span&gt;;
            &lt;span style="font-weight: bold"&gt;}&lt;/span&gt;
        &lt;span style="font-weight: bold"&gt;}&lt;/span&gt;
    &lt;span style="font-weight: bold"&gt;}&lt;/span&gt;
&lt;span style="font-weight: bold"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Which is nice because it disposes of both the connection and the dataReader 
properly on failure, but ugly because it uses a whole bunch of boilerplate.  
Unfortunately, because doSomething() needs to execute inside both 
&lt;code&gt;using&lt;/code&gt; statements, and we weren't using C# 2.0 until a few months 
ago, the only way to avoid the boilerplate would have been to pass in 
delegates.
&lt;p&gt;This would have been just as ugly as keeping the boilerplate in the code, so 
we stuck with the using&lt;sup&gt;2&lt;/sup&gt; idiom.
&lt;p&gt;Since our switchover to 2.0 a few months ago, I've had an idea that I could 
make this idiom more concise and remove some boilerplate that I didn't get a 
chance to try until this week. Using 2.0's iterators, which seem awfully 
familiar from my python work, that can be reduced to:
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span style="font-weight: bold"&gt;class&lt;/span&gt; &lt;span style="color: #445588; font-weight: bold"&gt;Something&lt;/span&gt;
&lt;span style="font-weight: bold"&gt;{&lt;/span&gt;
    &lt;span style="font-weight: bold"&gt;public&lt;/span&gt; &lt;span style="color: #445588; font-weight: bold"&gt;int&lt;/span&gt; &lt;span style="color: #990000; font-weight: bold"&gt;ourIdiom&lt;/span&gt;(&lt;span style="color: #445588; font-weight: bold"&gt;long&lt;/span&gt; identifier)
    &lt;span style="font-weight: bold"&gt;{&lt;/span&gt;
        &lt;span style="font-weight: bold"&gt;foreach&lt;/span&gt; (IDataReader rec &lt;span style="font-weight: bold"&gt;in&lt;/span&gt; &lt;span style="font-weight: bold"&gt;new&lt;/span&gt; SQL().Query(&lt;span style="color: #bb8844"&gt;@&amp;quot;&lt;/span&gt;
&lt;span style="color: #bb8844"&gt;            SELECT some, rows&lt;/span&gt;
&lt;span style="color: #bb8844"&gt;            FROM  Table1 t1, Table2 t2&lt;/span&gt;
&lt;span style="color: #bb8844"&gt;            WHERE t1.t2id = t2.id&lt;/span&gt;
&lt;span style="color: #bb8844"&gt;            AND   t1.id = ?&amp;quot;&lt;/span&gt;,
            identifier))
        &lt;span style="font-weight: bold"&gt;{&lt;/span&gt;
            doSomething();
        &lt;span style="font-weight: bold"&gt;}&lt;/span&gt;
        &lt;span style="font-weight: bold"&gt;return&lt;/span&gt; &lt;span style="color: #009999"&gt;1&lt;/span&gt;;
    &lt;span style="font-weight: bold"&gt;}&lt;/span&gt;
&lt;span style="font-weight: bold"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;With some fairly simple code:
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span style="font-weight: bold"&gt;public&lt;/span&gt; &lt;span style="font-weight: bold"&gt;class&lt;/span&gt; &lt;span style="color: #445588; font-weight: bold"&gt;SQL&lt;/span&gt; : 
    System.Collections.Generic.IEnumerable&amp;lt;IDataReader&amp;gt;
    &lt;span style="font-weight: bold"&gt;{&lt;/span&gt;
        &lt;span style="color: #445588; font-weight: bold"&gt;string&lt;/span&gt; m_sql;
        ArrayList m_sqlparams;

        &lt;span style="font-weight: bold"&gt;public&lt;/span&gt; &lt;span style="color: #990000; font-weight: bold"&gt;SQL&lt;/span&gt;()
        &lt;span style="font-weight: bold"&gt;{&lt;/span&gt;
        &lt;span style="font-weight: bold"&gt;}&lt;/span&gt;

        &lt;span style="font-weight: bold"&gt;public&lt;/span&gt; SQL &lt;span style="color: #990000; font-weight: bold"&gt;query&lt;/span&gt;(&lt;span style="color: #445588; font-weight: bold"&gt;string&lt;/span&gt; sql, &lt;span style="font-weight: bold"&gt;params&lt;/span&gt; &lt;span style="color: #445588; font-weight: bold"&gt;object&lt;/span&gt;[] sqlparams)
        &lt;span style="font-weight: bold"&gt;{&lt;/span&gt;
            m_sql = sql;
            m_sqlparams = &lt;span style="font-weight: bold"&gt;new&lt;/span&gt; ArrayList(sqlparams);
            &lt;span style="font-weight: bold"&gt;return&lt;/span&gt; &lt;span style="font-weight: bold"&gt;this&lt;/span&gt;;
        &lt;span style="font-weight: bold"&gt;}&lt;/span&gt;

        IEnumerator&amp;lt;IDataReader&amp;gt; IEnumerable&amp;lt;IDataReader&amp;gt;.GetEnumerator()
        &lt;span style="font-weight: bold"&gt;{&lt;/span&gt;
            &lt;span style="font-weight: bold"&gt;using&lt;/span&gt; (clsDBConnection db = &lt;span style="font-weight: bold"&gt;new&lt;/span&gt; clsDBConnection(m_dbname))
            &lt;span style="font-weight: bold"&gt;{&lt;/span&gt;
                &lt;span style="font-weight: bold"&gt;using&lt;/span&gt; (IDataReader rec = db.execQuery(m_sql, m_sqlparams))
                &lt;span style="font-weight: bold"&gt;{&lt;/span&gt;
                    &lt;span style="font-weight: bold"&gt;while&lt;/span&gt; (rec.Read())
                        yield &lt;span style="font-weight: bold"&gt;return&lt;/span&gt; rec;
                &lt;span style="font-weight: bold"&gt;}&lt;/span&gt;
            &lt;span style="font-weight: bold"&gt;}&lt;/span&gt;
        &lt;span style="font-weight: bold"&gt;}&lt;/span&gt;

        &lt;span style="color: #999988; font-style: italic"&gt;//this is required because IEnumerable&amp;lt;&amp;gt; inherits IEnumerable. bleh.&lt;/span&gt;
        IEnumerator IEnumerable.GetEnumerator() &lt;span style="font-weight: bold"&gt;{&lt;/span&gt; &lt;span style="font-weight: bold"&gt;return&lt;/span&gt; GetEnumerator() &lt;span style="font-weight: bold"&gt;}&lt;/span&gt;
    &lt;span style="font-weight: bold"&gt;}&lt;/span&gt;
&lt;span style="font-weight: bold"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;This code should come in handy for more reasons than just its cleanliness.  
First off, if you ever need to change the idiom for accessing the DB, it's 
stored conveniently in one place.
&lt;p&gt;Second, It makes a prepared SQL call into something like a &lt;a 
href="http://en.wikipedia.org/wiki/Thunk"&gt;thunk&lt;/a&gt;: a bit of code representing 
a future computation that can then be passed around to be performed later. An 
example:
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span style="font-weight: bold"&gt;void&lt;/span&gt; &lt;span style="color: #990000; font-weight: bold"&gt;setUpQueries&lt;/span&gt;(nameId, addressId, custId)
&lt;span style="font-weight: bold"&gt;{&lt;/span&gt;
    List&amp;lt;SQL&amp;gt; stringsWeNeed = &lt;span style="font-weight: bold"&gt;new&lt;/span&gt; List(&lt;span style="font-weight: bold"&gt;new&lt;/span&gt; &lt;span style="color: #445588; font-weight: bold"&gt;object&lt;/span&gt;[]&lt;span style="font-weight: bold"&gt;{&lt;/span&gt;
        &lt;span style="font-weight: bold"&gt;new&lt;/span&gt; &lt;span style="color: #990000; font-weight: bold"&gt;SQL&lt;/span&gt;().query(&lt;span style="color: #bb8844"&gt;&amp;quot;SELECT name FROM names WHERE id=?&amp;quot;&lt;/span&gt;, nameId),
        &lt;span style="font-weight: bold"&gt;new&lt;/span&gt; &lt;span style="color: #990000; font-weight: bold"&gt;SQL&lt;/span&gt;().query(&lt;span style="color: #bb8844"&gt;&amp;quot;SELECT addy FROM addresses WHERE id=?&amp;quot;&lt;/span&gt;, addressId),
        &lt;span style="font-weight: bold"&gt;new&lt;/span&gt; &lt;span style="color: #990000; font-weight: bold"&gt;SQL&lt;/span&gt;().query(&lt;span style="color: #bb8844"&gt;&amp;quot;SELECT zip FROM customers WHERE id=?&amp;quot;&lt;/span&gt;, custId)&lt;span style="font-weight: bold"&gt;}&lt;/span&gt;);

    List&amp;lt;&lt;span style="color: #445588; font-weight: bold"&gt;string&lt;/span&gt;&amp;gt; strings = getOurStrings(stringsWeNeed);

    mangleStrings(strings);
&lt;span style="font-weight: bold"&gt;}&lt;/span&gt;

List&amp;lt;&lt;span style="color: #445588; font-weight: bold"&gt;string&lt;/span&gt;&amp;gt; getOurStrings(List&amp;lt;SQL&amp;gt; queries)
&lt;span style="font-weight: bold"&gt;{&lt;/span&gt;
    List&amp;lt;&lt;span style="color: #445588; font-weight: bold"&gt;string&lt;/span&gt;&amp;gt; strings = &lt;span style="font-weight: bold"&gt;new&lt;/span&gt; List&amp;lt;&lt;span style="color: #445588; font-weight: bold"&gt;string&lt;/span&gt;&amp;gt;();
    &lt;span style="font-weight: bold"&gt;foreach&lt;/span&gt; (SQL query &lt;span style="font-weight: bold"&gt;in&lt;/span&gt; queries)
    &lt;span style="font-weight: bold"&gt;{&lt;/span&gt;
        &lt;span style="font-weight: bold"&gt;foreach&lt;/span&gt; (IDataReader rec &lt;span style="font-weight: bold"&gt;in&lt;/span&gt; query)
            strings.Add(rec.GetString(&lt;span style="color: #009999"&gt;0&lt;/span&gt;));
    &lt;span style="font-weight: bold"&gt;}&lt;/span&gt;
    &lt;span style="font-weight: bold"&gt;return&lt;/span&gt; strings;
&lt;span style="font-weight: bold"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;While the example is silly, this property can be exploited to seperate 
declaration from execution, which I often find to be a useful pattern.
&lt;p&gt;Though I am far from the &lt;a 
href="http://www.base4.net/blog.aspx?ID=409"&gt;first person&lt;/a&gt; to discover this 
simplification, I did figure it out on my own and I thought it was neat enough 
to share.
&lt;p&gt;A quick disclaimer: the code here is modified from the original to remove 
some details, and is completely untested, and probably doesn't compile.  You 
may, however, use it or distribute it as you see fit; it's licensed under the 
&lt;a href="http://sam.zoy.org/wtfpl/"&gt;wtfpl&lt;/a&gt;.
&lt;p&gt;UPDATE: added the while(rec.Read()), which I'd forgotten
</summary>
		<content type="html">&lt;p&gt;At my job, we use what is essentially a custom C# ORM. Soon after I arrived, 
we adopted this idiom to pull a DB connection from the pool and run a query:
&lt;div class="highlight"&gt;&lt;pre&gt; &lt;span style="font-weight: bold"&gt;class&lt;/span&gt; &lt;span style="color: #445588; font-weight: bold"&gt;Something&lt;/span&gt;
&lt;span style="font-weight: bold"&gt;{&lt;/span&gt;
    &lt;span style="font-weight: bold"&gt;public&lt;/span&gt; &lt;span style="color: #445588; font-weight: bold"&gt;int&lt;/span&gt; &lt;span style="color: #990000; font-weight: bold"&gt;ourIdiom&lt;/span&gt;(&lt;span style="color: #445588; font-weight: bold"&gt;long&lt;/span&gt; identifier)
    &lt;span style="font-weight: bold"&gt;{&lt;/span&gt;
        &lt;span style="font-weight: bold"&gt;using&lt;/span&gt; (DBConnection db = &lt;span style="font-weight: bold"&gt;new&lt;/span&gt; DBConnection())
        &lt;span style="font-weight: bold"&gt;{&lt;/span&gt;
            &lt;span style="font-weight: bold"&gt;using&lt;/span&gt; (IDataReader rec = db.execQuery(&lt;span style="color: #bb8844"&gt;@&amp;quot;&lt;/span&gt;
&lt;span style="color: #bb8844"&gt;                SELECT some, rows&lt;/span&gt;
&lt;span style="color: #bb8844"&gt;                FROM  Table1 t1, Table2 t2&lt;/span&gt;
&lt;span style="color: #bb8844"&gt;                WHERE t1.t2id = t2.id&lt;/span&gt;
&lt;span style="color: #bb8844"&gt;                AND   t1.id = ?&amp;quot;&lt;/span&gt;,
                identifier))
            &lt;span style="font-weight: bold"&gt;{&lt;/span&gt;
                &lt;span style="font-weight: bold"&gt;while&lt;/span&gt; (rec.Read())
                    doSomething();
                &lt;span style="font-weight: bold"&gt;return&lt;/span&gt; &lt;span style="color: #009999"&gt;1&lt;/span&gt;;
            &lt;span style="font-weight: bold"&gt;}&lt;/span&gt;
        &lt;span style="font-weight: bold"&gt;}&lt;/span&gt;
    &lt;span style="font-weight: bold"&gt;}&lt;/span&gt;
&lt;span style="font-weight: bold"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Which is nice because it disposes of both the connection and the dataReader 
properly on failure, but ugly because it uses a whole bunch of boilerplate.  
Unfortunately, because doSomething() needs to execute inside both 
&lt;code&gt;using&lt;/code&gt; statements, and we weren't using C# 2.0 until a few months 
ago, the only way to avoid the boilerplate would have been to pass in 
delegates.
&lt;p&gt;This would have been just as ugly as keeping the boilerplate in the code, so 
we stuck with the using&lt;sup&gt;2&lt;/sup&gt; idiom.
&lt;p&gt;Since our switchover to 2.0 a few months ago, I've had an idea that I could 
make this idiom more concise and remove some boilerplate that I didn't get a 
chance to try until this week. Using 2.0's iterators, which seem awfully 
familiar from my python work, that can be reduced to:
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span style="font-weight: bold"&gt;class&lt;/span&gt; &lt;span style="color: #445588; font-weight: bold"&gt;Something&lt;/span&gt;
&lt;span style="font-weight: bold"&gt;{&lt;/span&gt;
    &lt;span style="font-weight: bold"&gt;public&lt;/span&gt; &lt;span style="color: #445588; font-weight: bold"&gt;int&lt;/span&gt; &lt;span style="color: #990000; font-weight: bold"&gt;ourIdiom&lt;/span&gt;(&lt;span style="color: #445588; font-weight: bold"&gt;long&lt;/span&gt; identifier)
    &lt;span style="font-weight: bold"&gt;{&lt;/span&gt;
        &lt;span style="font-weight: bold"&gt;foreach&lt;/span&gt; (IDataReader rec &lt;span style="font-weight: bold"&gt;in&lt;/span&gt; &lt;span style="font-weight: bold"&gt;new&lt;/span&gt; SQL().Query(&lt;span style="color: #bb8844"&gt;@&amp;quot;&lt;/span&gt;
&lt;span style="color: #bb8844"&gt;            SELECT some, rows&lt;/span&gt;
&lt;span style="color: #bb8844"&gt;            FROM  Table1 t1, Table2 t2&lt;/span&gt;
&lt;span style="color: #bb8844"&gt;            WHERE t1.t2id = t2.id&lt;/span&gt;
&lt;span style="color: #bb8844"&gt;            AND   t1.id = ?&amp;quot;&lt;/span&gt;,
            identifier))
        &lt;span style="font-weight: bold"&gt;{&lt;/span&gt;
            doSomething();
        &lt;span style="font-weight: bold"&gt;}&lt;/span&gt;
        &lt;span style="font-weight: bold"&gt;return&lt;/span&gt; &lt;span style="color: #009999"&gt;1&lt;/span&gt;;
    &lt;span style="font-weight: bold"&gt;}&lt;/span&gt;
&lt;span style="font-weight: bold"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;With some fairly simple code:
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span style="font-weight: bold"&gt;public&lt;/span&gt; &lt;span style="font-weight: bold"&gt;class&lt;/span&gt; &lt;span style="color: #445588; font-weight: bold"&gt;SQL&lt;/span&gt; : 
    System.Collections.Generic.IEnumerable&amp;lt;IDataReader&amp;gt;
    &lt;span style="font-weight: bold"&gt;{&lt;/span&gt;
        &lt;span style="color: #445588; font-weight: bold"&gt;string&lt;/span&gt; m_sql;
        ArrayList m_sqlparams;

        &lt;span style="font-weight: bold"&gt;public&lt;/span&gt; &lt;span style="color: #990000; font-weight: bold"&gt;SQL&lt;/span&gt;()
        &lt;span style="font-weight: bold"&gt;{&lt;/span&gt;
        &lt;span style="font-weight: bold"&gt;}&lt;/span&gt;

        &lt;span style="font-weight: bold"&gt;public&lt;/span&gt; SQL &lt;span style="color: #990000; font-weight: bold"&gt;query&lt;/span&gt;(&lt;span style="color: #445588; font-weight: bold"&gt;string&lt;/span&gt; sql, &lt;span style="font-weight: bold"&gt;params&lt;/span&gt; &lt;span style="color: #445588; font-weight: bold"&gt;object&lt;/span&gt;[] sqlparams)
        &lt;span style="font-weight: bold"&gt;{&lt;/span&gt;
            m_sql = sql;
            m_sqlparams = &lt;span style="font-weight: bold"&gt;new&lt;/span&gt; ArrayList(sqlparams);
            &lt;span style="font-weight: bold"&gt;return&lt;/span&gt; &lt;span style="font-weight: bold"&gt;this&lt;/span&gt;;
        &lt;span style="font-weight: bold"&gt;}&lt;/span&gt;

        IEnumerator&amp;lt;IDataReader&amp;gt; IEnumerable&amp;lt;IDataReader&amp;gt;.GetEnumerator()
        &lt;span style="font-weight: bold"&gt;{&lt;/span&gt;
            &lt;span style="font-weight: bold"&gt;using&lt;/span&gt; (clsDBConnection db = &lt;span style="font-weight: bold"&gt;new&lt;/span&gt; clsDBConnection(m_dbname))
            &lt;span style="font-weight: bold"&gt;{&lt;/span&gt;
                &lt;span style="font-weight: bold"&gt;using&lt;/span&gt; (IDataReader rec = db.execQuery(m_sql, m_sqlparams))
                &lt;span style="font-weight: bold"&gt;{&lt;/span&gt;
                    &lt;span style="font-weight: bold"&gt;while&lt;/span&gt; (rec.Read())
                        yield &lt;span style="font-weight: bold"&gt;return&lt;/span&gt; rec;
                &lt;span style="font-weight: bold"&gt;}&lt;/span&gt;
            &lt;span style="font-weight: bold"&gt;}&lt;/span&gt;
        &lt;span style="font-weight: bold"&gt;}&lt;/span&gt;

        &lt;span style="color: #999988; font-style: italic"&gt;//this is required because IEnumerable&amp;lt;&amp;gt; inherits IEnumerable. bleh.&lt;/span&gt;
        IEnumerator IEnumerable.GetEnumerator() &lt;span style="font-weight: bold"&gt;{&lt;/span&gt; &lt;span style="font-weight: bold"&gt;return&lt;/span&gt; GetEnumerator() &lt;span style="font-weight: bold"&gt;}&lt;/span&gt;
    &lt;span style="font-weight: bold"&gt;}&lt;/span&gt;
&lt;span style="font-weight: bold"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;This code should come in handy for more reasons than just its cleanliness.  
First off, if you ever need to change the idiom for accessing the DB, it's 
stored conveniently in one place.
&lt;p&gt;Second, It makes a prepared SQL call into something like a &lt;a 
href="http://en.wikipedia.org/wiki/Thunk"&gt;thunk&lt;/a&gt;: a bit of code representing 
a future computation that can then be passed around to be performed later. An 
example:
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span style="font-weight: bold"&gt;void&lt;/span&gt; &lt;span style="color: #990000; font-weight: bold"&gt;setUpQueries&lt;/span&gt;(nameId, addressId, custId)
&lt;span style="font-weight: bold"&gt;{&lt;/span&gt;
    List&amp;lt;SQL&amp;gt; stringsWeNeed = &lt;span style="font-weight: bold"&gt;new&lt;/span&gt; List(&lt;span style="font-weight: bold"&gt;new&lt;/span&gt; &lt;span style="color: #445588; font-weight: bold"&gt;object&lt;/span&gt;[]&lt;span style="font-weight: bold"&gt;{&lt;/span&gt;
        &lt;span style="font-weight: bold"&gt;new&lt;/span&gt; &lt;span style="color: #990000; font-weight: bold"&gt;SQL&lt;/span&gt;().query(&lt;span style="color: #bb8844"&gt;&amp;quot;SELECT name FROM names WHERE id=?&amp;quot;&lt;/span&gt;, nameId),
        &lt;span style="font-weight: bold"&gt;new&lt;/span&gt; &lt;span style="color: #990000; font-weight: bold"&gt;SQL&lt;/span&gt;().query(&lt;span style="color: #bb8844"&gt;&amp;quot;SELECT addy FROM addresses WHERE id=?&amp;quot;&lt;/span&gt;, addressId),
        &lt;span style="font-weight: bold"&gt;new&lt;/span&gt; &lt;span style="color: #990000; font-weight: bold"&gt;SQL&lt;/span&gt;().query(&lt;span style="color: #bb8844"&gt;&amp;quot;SELECT zip FROM customers WHERE id=?&amp;quot;&lt;/span&gt;, custId)&lt;span style="font-weight: bold"&gt;}&lt;/span&gt;);

    List&amp;lt;&lt;span style="color: #445588; font-weight: bold"&gt;string&lt;/span&gt;&amp;gt; strings = getOurStrings(stringsWeNeed);

    mangleStrings(strings);
&lt;span style="font-weight: bold"&gt;}&lt;/span&gt;

List&amp;lt;&lt;span style="color: #445588; font-weight: bold"&gt;string&lt;/span&gt;&amp;gt; getOurStrings(List&amp;lt;SQL&amp;gt; queries)
&lt;span style="font-weight: bold"&gt;{&lt;/span&gt;
    List&amp;lt;&lt;span style="color: #445588; font-weight: bold"&gt;string&lt;/span&gt;&amp;gt; strings = &lt;span style="font-weight: bold"&gt;new&lt;/span&gt; List&amp;lt;&lt;span style="color: #445588; font-weight: bold"&gt;string&lt;/span&gt;&amp;gt;();
    &lt;span style="font-weight: bold"&gt;foreach&lt;/span&gt; (SQL query &lt;span style="font-weight: bold"&gt;in&lt;/span&gt; queries)
    &lt;span style="font-weight: bold"&gt;{&lt;/span&gt;
        &lt;span style="font-weight: bold"&gt;foreach&lt;/span&gt; (IDataReader rec &lt;span style="font-weight: bold"&gt;in&lt;/span&gt; query)
            strings.Add(rec.GetString(&lt;span style="color: #009999"&gt;0&lt;/span&gt;));
    &lt;span style="font-weight: bold"&gt;}&lt;/span&gt;
    &lt;span style="font-weight: bold"&gt;return&lt;/span&gt; strings;
&lt;span style="font-weight: bold"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;While the example is silly, this property can be exploited to seperate 
declaration from execution, which I often find to be a useful pattern.
&lt;p&gt;Though I am far from the &lt;a 
href="http://www.base4.net/blog.aspx?ID=409"&gt;first person&lt;/a&gt; to discover this 
simplification, I did figure it out on my own and I thought it was neat enough 
to share.
&lt;p&gt;A quick disclaimer: the code here is modified from the original to remove 
some details, and is completely untested, and probably doesn't compile.  You 
may, however, use it or distribute it as you see fit; it's licensed under the 
&lt;a href="http://sam.zoy.org/wtfpl/"&gt;wtfpl&lt;/a&gt;.
&lt;p&gt;UPDATE: added the while(rec.Read()), which I'd forgotten
</content>
	</entry>
	<entry>
		<title>Why Applications Suck (Part 1)</title>
		<link href="http://billmill.org/why_apps_suck.html" />	
		<id>http://billmill.org/why_apps_suck.html</id>
		<updated>2007-08-24T01:50:00Z</updated>
		<summary type="html">Why do people outside of corporations overwhelmingly use webmail instead of 
email clients? Long before rich email clients like gmail were available, people 
have flocked to the internet email client - messaging has been the killer 
feature of the web for a long time now.&lt;p&gt;
But why?&lt;p&gt;
The answer is simple: Overwhelmingly, users do not want to install programs, 
and users do not want their data stored on their computer. In that order of 
importance.&lt;p&gt;
&lt;h2&gt;Users Don't Want to Install Programs&lt;/h2&gt;&lt;p&gt;
Let's examine the process of getting a popular, free, email client like &lt;a 
href="http://www.mozilla.com/en-US/thunderbird/"&gt;Thunderbird&lt;/a&gt; installed. To 
do so, imagine that we're instructing our kindly aunt Tilly how to install 
it.&lt;p&gt;
Now Tilly is no old fogie, she's been using Microsoft Word at work for over a 
decade now, and she knows her way around msn.com. However, she just decided to 
strike out looking for a new job, and wants to finally use that personal email 
address that came with her cable internet. She's got us trapped on the phone, 
and "we know computers", so here's roughly what we'll tell her to do:&lt;p&gt;
&lt;ol&gt;&lt;li&gt;type google.com in the address bar
&lt;li&gt;type in "thunderbird"; press enter
&lt;li&gt;click on the first result
&lt;li&gt;click on "Download Thunderbird"
&lt;li&gt;click "OK"
&lt;li&gt;choose a place to save it (Just use the desktop, Tilly!)
&lt;li&gt;minimize the browser
&lt;li&gt;hunt for the file named "Thunderbird"
&lt;/ol&gt;&lt;p&gt;

And, ohmigod, we're not even close to done. She's still got to run the 
installer (3-4 clicks minimum), which involves selecting an installation 
directory (a what?), then open the program, open the tools -&gt; accounts menu 
option, find the documentation for her service provider's email tools, copy 
them into the "add new account" wizard (another 3-4 clicks) where appropriate, 
remember her user name and password, and then download all the email she's had 
sitting there since she hasn't checked it ever.&lt;p&gt;
Now, finally, she's ready to use her email client. It's just that easy!&lt;p&gt;
Let's compare the process for getting her up and running with gmail:&lt;p&gt;
&lt;ol&gt;&lt;li&gt;type "gmail.com" in the address bar
&lt;li&gt;click on "sign up for gmail"
&lt;li&gt;fill out a form (a task she probably knows how to do)
&lt;li&gt;click on "I accept. Create my account."
&lt;/ol&gt;&lt;p&gt;
Now, Tilly may not be the most technological mind around, but she's also no 
dummy. I know which one I'd rather direct her to do.&lt;p&gt;
Desktop application install is a problem.&lt;p&gt;
&lt;h2&gt;Do We Even Want to Fix This?&lt;/h2&gt;
Many web 2.0-savvy types will tell us that this isn't a big deal. In the 
future, all of our applications should be inside our browser, and to speak 
otherwise is heresy!  The desktop is dead! Sure, Javascript + Json + the 
browser has limitations, but those restrictions are liberating! Get used to it, 
or perish!&lt;/p&gt;
Well, bah humbug. Here's what's good about the web: The easy posting, viewing, 
and navigating of documents described by URIs.&lt;p&gt;
That's it.&lt;p&gt;
Let me repeat it for clarity: The web, in your browser, is &lt;em&gt;only really good 
at&lt;/em&gt; sending discrete data, displaying discrete documents and navigating in between 
them.&lt;p&gt;
Phew.&lt;p&gt;
The whole paradigm is absolutely superb at getting this job done. The system of 
hyperlinks, URIs, DNS, and HTTP over TCP/IP is the greatest achievement that 
computer programmers have achieved, a massive global effort that has managed to  
stay amazingly open and coherent. It "Just Works" enough to change the way 
information is distributed, businesses are run and even how society is 
structured.&lt;p&gt;
Anything amenable to being represented as discrete visual documents has taken 
to the internet like a duck to water. Chief among them is email; check out the 
&lt;a href="http://www.alexa.com/site/ds/top_sites?ts_mode=global&amp;lang=none"&gt;top 
100 global&lt;/a&gt; Alexa websites and see how many "social networks" in how many 
languages are in the top 100. Sites displaying news (documents), photographs 
(documents), videos (strictly as documents), and information about software 
(documents) make up most of the rest.&lt;p&gt;
What's left among those 100 is the elephant in the room; the Killer Internet 
Application: search. Even Microsoft's lame search engine finds its way into the 
top 100 because people will do whatever they need to in order to search the 
web; it's the only way to get an effective handle on the information in the 
Great Hyperlinked Mass. I believe it's the exception to my "web is only good at 
documents" theory that proves the rule.&lt;p&gt;
&lt;h2&gt;Search Works, so Let's Put All our Apps On the Web&lt;/h2&gt;
Since the web gained massive worldwide popularity in the mid-1990s, an enormous 
amount of effort has been spent on making the browser into an application 
development platform.  The Great Mozilla Rewrite basically shut that browser 
down between 1998 and 2002 in order to make it an application platform.  
Microsoft developed activeX, Sun pushed Java applets as the solution, Adobe 
developed SVG, and Macromedia developed its Flash player.&lt;p&gt;
Nowadays, Firefox is pushing &amp;lt;canvas&amp;gt;, Microsoft has released 
Silverlight, Macromedia has become Adobe, and Flash is the only one of the 
first generation technologies still breathing oxygen as a development 
platform.&lt;p&gt;
Furthermore, with the invention of Google Gears, &lt;a 
href="http://joyeur.com/2007/03/22/joyent-slingshot"&gt;Joyent Slingshot&lt;/a&gt;, the 
aforementioned Silverlight, or Adobe Air, you might soon be able to (gasp) save 
files to the host computer! That's right, in 10 years we've almost gotten to 
the point where a program running in a browser can save a file on your hard 
drive and read it when you're offline.&lt;p&gt;
The problem is that, fundamentally, a browser is &lt;em&gt;still&lt;/em&gt; only good at 
one thing: documents. Its whole paradigm is set up that way. What does the 
"back button" mean when you're playing a game of asteroids? What does "home" 
mean while you're editing a photo? Does an address bar on an mp3 player need to 
be so &lt;em&gt;in your face&lt;/em&gt;?&lt;p&gt;
&lt;h2&gt;We Can Fix This&lt;/h2&gt;
So, instead of shoehorning our applications inside of the browser window 
because it's convenient, let's do something radical: bring our "real software" 
applications into the modern age of the internet.&lt;p&gt;
In the &lt;a href="why_apps_suck2.html"&gt;next article&lt;/a&gt;, we'll talk about how 
software installation came to suck so 
badly, with an eye towards how to go about bringing it up to the web era.&lt;p&gt;
</summary>
		<content type="html">Why do people outside of corporations overwhelmingly use webmail instead of 
email clients? Long before rich email clients like gmail were available, people 
have flocked to the internet email client - messaging has been the killer 
feature of the web for a long time now.&lt;p&gt;
But why?&lt;p&gt;
The answer is simple: Overwhelmingly, users do not want to install programs, 
and users do not want their data stored on their computer. In that order of 
importance.&lt;p&gt;
&lt;h2&gt;Users Don't Want to Install Programs&lt;/h2&gt;&lt;p&gt;
Let's examine the process of getting a popular, free, email client like &lt;a 
href="http://www.mozilla.com/en-US/thunderbird/"&gt;Thunderbird&lt;/a&gt; installed. To 
do so, imagine that we're instructing our kindly aunt Tilly how to install 
it.&lt;p&gt;
Now Tilly is no old fogie, she's been using Microsoft Word at work for over a 
decade now, and she knows her way around msn.com. However, she just decided to 
strike out looking for a new job, and wants to finally use that personal email 
address that came with her cable internet. She's got us trapped on the phone, 
and "we know computers", so here's roughly what we'll tell her to do:&lt;p&gt;
&lt;ol&gt;&lt;li&gt;type google.com in the address bar
&lt;li&gt;type in "thunderbird"; press enter
&lt;li&gt;click on the first result
&lt;li&gt;click on "Download Thunderbird"
&lt;li&gt;click "OK"
&lt;li&gt;choose a place to save it (Just use the desktop, Tilly!)
&lt;li&gt;minimize the browser
&lt;li&gt;hunt for the file named "Thunderbird"
&lt;/ol&gt;&lt;p&gt;

And, ohmigod, we're not even close to done. She's still got to run the 
installer (3-4 clicks minimum), which involves selecting an installation 
directory (a what?), then open the program, open the tools -&gt; accounts menu 
option, find the documentation for her service provider's email tools, copy 
them into the "add new account" wizard (another 3-4 clicks) where appropriate, 
remember her user name and password, and then download all the email she's had 
sitting there since she hasn't checked it ever.&lt;p&gt;
Now, finally, she's ready to use her email client. It's just that easy!&lt;p&gt;
Let's compare the process for getting her up and running with gmail:&lt;p&gt;
&lt;ol&gt;&lt;li&gt;type "gmail.com" in the address bar
&lt;li&gt;click on "sign up for gmail"
&lt;li&gt;fill out a form (a task she probably knows how to do)
&lt;li&gt;click on "I accept. Create my account."
&lt;/ol&gt;&lt;p&gt;
Now, Tilly may not be the most technological mind around, but she's also no 
dummy. I know which one I'd rather direct her to do.&lt;p&gt;
Desktop application install is a problem.&lt;p&gt;
&lt;h2&gt;Do We Even Want to Fix This?&lt;/h2&gt;
Many web 2.0-savvy types will tell us that this isn't a big deal. In the 
future, all of our applications should be inside our browser, and to speak 
otherwise is heresy!  The desktop is dead! Sure, Javascript + Json + the 
browser has limitations, but those restrictions are liberating! Get used to it, 
or perish!&lt;/p&gt;
Well, bah humbug. Here's what's good about the web: The easy posting, viewing, 
and navigating of documents described by URIs.&lt;p&gt;
That's it.&lt;p&gt;
Let me repeat it for clarity: The web, in your browser, is &lt;em&gt;only really good 
at&lt;/em&gt; sending discrete data, displaying discrete documents and navigating in between 
them.&lt;p&gt;
Phew.&lt;p&gt;
The whole paradigm is absolutely superb at getting this job done. The system of 
hyperlinks, URIs, DNS, and HTTP over TCP/IP is the greatest achievement that 
computer programmers have achieved, a massive global effort that has managed to  
stay amazingly open and coherent. It "Just Works" enough to change the way 
information is distributed, businesses are run and even how society is 
structured.&lt;p&gt;
Anything amenable to being represented as discrete visual documents has taken 
to the internet like a duck to water. Chief among them is email; check out the 
&lt;a href="http://www.alexa.com/site/ds/top_sites?ts_mode=global&amp;lang=none"&gt;top 
100 global&lt;/a&gt; Alexa websites and see how many "social networks" in how many 
languages are in the top 100. Sites displaying news (documents), photographs 
(documents), videos (strictly as documents), and information about software 
(documents) make up most of the rest.&lt;p&gt;
What's left among those 100 is the elephant in the room; the Killer Internet 
Application: search. Even Microsoft's lame search engine finds its way into the 
top 100 because people will do whatever they need to in order to search the 
web; it's the only way to get an effective handle on the information in the 
Great Hyperlinked Mass. I believe it's the exception to my "web is only good at 
documents" theory that proves the rule.&lt;p&gt;
&lt;h2&gt;Search Works, so Let's Put All our Apps On the Web&lt;/h2&gt;
Since the web gained massive worldwide popularity in the mid-1990s, an enormous 
amount of effort has been spent on making the browser into an application 
development platform.  The Great Mozilla Rewrite basically shut that browser 
down between 1998 and 2002 in order to make it an application platform.  
Microsoft developed activeX, Sun pushed Java applets as the solution, Adobe 
developed SVG, and Macromedia developed its Flash player.&lt;p&gt;
Nowadays, Firefox is pushing &amp;lt;canvas&amp;gt;, Microsoft has released 
Silverlight, Macromedia has become Adobe, and Flash is the only one of the 
first generation technologies still breathing oxygen as a development 
platform.&lt;p&gt;
Furthermore, with the invention of Google Gears, &lt;a 
href="http://joyeur.com/2007/03/22/joyent-slingshot"&gt;Joyent Slingshot&lt;/a&gt;, the 
aforementioned Silverlight, or Adobe Air, you might soon be able to (gasp) save 
files to the host computer! That's right, in 10 years we've almost gotten to 
the point where a program running in a browser can save a file on your hard 
drive and read it when you're offline.&lt;p&gt;
The problem is that, fundamentally, a browser is &lt;em&gt;still&lt;/em&gt; only good at 
one thing: documents. Its whole paradigm is set up that way. What does the 
"back button" mean when you're playing a game of asteroids? What does "home" 
mean while you're editing a photo? Does an address bar on an mp3 player need to 
be so &lt;em&gt;in your face&lt;/em&gt;?&lt;p&gt;
&lt;h2&gt;We Can Fix This&lt;/h2&gt;
So, instead of shoehorning our applications inside of the browser window 
because it's convenient, let's do something radical: bring our "real software" 
applications into the modern age of the internet.&lt;p&gt;
In the &lt;a href="why_apps_suck2.html"&gt;next article&lt;/a&gt;, we'll talk about how 
software installation came to suck so 
badly, with an eye towards how to go about bringing it up to the web era.&lt;p&gt;
</content>
	</entry>
</feed>
