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

<channel>
	<title>Inadvertent incorrectness</title>
	<atom:link href="http://ken.friislarsen.net/blog/feed/" rel="self" type="application/rss+xml" />
	<link>http://ken.friislarsen.net/blog</link>
	<description>... but that doesn&#039;t matter, because I turn it into a sexy dance</description>
	<lastBuildDate>Thu, 11 Sep 2008 20:01:45 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.9.2</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>I Am Going to JAOO 2008 As A F# Expert</title>
		<link>http://ken.friislarsen.net/blog/2008/09/11/i-am-going-to-jaoo-2008-as-a-f-expert/</link>
		<comments>http://ken.friislarsen.net/blog/2008/09/11/i-am-going-to-jaoo-2008-as-a-f-expert/#comments</comments>
		<pubDate>Thu, 11 Sep 2008 20:01:45 +0000</pubDate>
		<dc:creator>Ken</dc:creator>
				<category><![CDATA[Coding]]></category>
		<category><![CDATA[F#]]></category>

		<guid isPermaLink="false">http://ken.friislarsen.net/blog/2008/09/11/i-am-going-to-jaoo-2008-as-a-f-expert/</guid>
		<description><![CDATA[Microsoft Denmark have invited me to participate in JAOO 2008. If I in return spend some time in the Microsoft stand demoing F# and answering questions about F# and functional programming in general.
When Martin Esmann (Microsoft Academic Developer Evangelist) approached me, I told him that I&#8217;d be happy to show up, but I&#8217;m not using [...]]]></description>
			<content:encoded><![CDATA[<p>Microsoft Denmark have invited me to participate in <a href="http://jaoo.dk">JAOO 2008</a>. If I in return spend some time in the Microsoft stand demoing <a href="http://research.microsoft.com/fsharp/fsharp.aspx">F#</a> and answering questions about F# and functional programming in general.</p>
<p>When <a href="http://blogs.msdn.com/mesmann">Martin Esmann</a> (Microsoft Academic Developer Evangelist) approached me, I told him that I&#8217;d be happy to show up, but I&#8217;m not using F# from within Visual Studio. In fact, I&#8217;m usually not even using Microsoft&#8217;s .NET implementation. I&#8217;m a happy <a href="http://www.mono-project.com">Mono</a> user. To Martin&#8217;s credit his initial reaction was that it would be cool that I demoed F# using Linux and Mono in the Microsoft stand.</p>
<p>However, after talking it over with his colleges, Martin got back to me and told me that they thought that using Linux and Mono to demo F# would send to mixed a message. I agree with that. So unfortunately I won&#8217;t be demoing Mono in a Microsoft stand this time. But I&#8217;ll of course bring my own laptop, and might show F# on Mono and Linux if there are questions about portability. Maybe I should contact the Mono guys and ask for a T-shirt, so that I silently can invite questions about Mono  <img src='http://ken.friislarsen.net/blog/wp-includes/images/smilies/icon_wink.gif' alt=';-)' class='wp-smiley' /> </p>
<p>Time to practice some F# demos.  Any suggestions for what would be effective? I&#8217;m planning to show of the brand new Units of Measure and also sequence comprehensions.</p>
]]></content:encoded>
			<wfw:commentRss>http://ken.friislarsen.net/blog/2008/09/11/i-am-going-to-jaoo-2008-as-a-f-expert/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Getting Ready for the ICFP 2008 Programming Contest</title>
		<link>http://ken.friislarsen.net/blog/2008/07/11/getting-ready-for-the-icfp-2008-programming-contest/</link>
		<comments>http://ken.friislarsen.net/blog/2008/07/11/getting-ready-for-the-icfp-2008-programming-contest/#comments</comments>
		<pubDate>Fri, 11 Jul 2008 13:30:18 +0000</pubDate>
		<dc:creator>Ken</dc:creator>
				<category><![CDATA[Coding]]></category>

		<guid isPermaLink="false">http://ken.friislarsen.net/blog/2008/07/11/getting-ready-for-the-icfp-2008-programming-contest/</guid>
		<description><![CDATA[I&#8217;m getting ready to participate in the eleventh ICFP programming contest.
So far everything works like a charm, KVM can run the LiveCD for the contest without a problem:

kvm -cdrom ICFPCD15.iso &#38;

I hope I&#8217;ll be able to spend more time on the contest compared to last time I participated.
]]></description>
			<content:encoded><![CDATA[<p>I&#8217;m getting ready to participate in <a href="http://icfpcontest.org">the eleventh ICFP programming contest</a>.</p>
<p>So far everything works like a charm, KVM can run <a href="http://www.icfpcontest.org/live-cd.html">the LiveCD for the contest</a> without a problem:<br />
<code><br />
kvm -cdrom ICFPCD15.iso &amp;<br />
</code></p>
<p>I hope I&#8217;ll be able to spend more time on the contest compared to <a href="http://ken.friislarsen.net/blog/2006/07/27/icfp-contest-2006-team-kfl/">last time I participated</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://ken.friislarsen.net/blog/2008/07/11/getting-ready-for-the-icfp-2008-programming-contest/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Decoding Morse Code With F# Comprehensions</title>
		<link>http://ken.friislarsen.net/blog/2007/11/09/decoding-morse-code-with-f-comprehensions/</link>
		<comments>http://ken.friislarsen.net/blog/2007/11/09/decoding-morse-code-with-f-comprehensions/#comments</comments>
		<pubDate>Fri, 09 Nov 2007 11:31:30 +0000</pubDate>
		<dc:creator>Ken</dc:creator>
				<category><![CDATA[F#]]></category>
		<category><![CDATA[General]]></category>
		<category><![CDATA[Python]]></category>

		<guid isPermaLink="false">http://ken.friislarsen.net/blog/2007/11/09/decoding-morse-code-with-f-comprehensions/</guid>
		<description><![CDATA[In my last post I showed how to decode morse code in Python using list comprehensions.  In this post I will show how to do it in F# instead.
First using list comprehensions:
let codes =
    [("A",".-");   ("B","-..."); ("C","-.-."); ("D","-.."); ("E",".");
     ("F","..-."); ("G","--.");  ("H","...."); ("I","..");  [...]]]></description>
			<content:encoded><![CDATA[<p>In my last post I showed how to <a href="http://ken.friislarsen.net/blog/2007/09/19/morse-code-decoding-with-python-list-comprehensions/">decode morse code in Python using list comprehensions</a>.  In this post I will show how to do it in <a href="http://research.microsoft.com/fsharp/fsharp.aspx">F#</a> instead.</p>
<p>First using list comprehensions:</p>
<pre>let codes =
    [("A",".-");   ("B","-..."); ("C","-.-."); ("D","-.."); ("E",".");
     ("F","..-."); ("G","--.");  ("H","...."); ("I","..");  ("J",".---");
     ("K","-.-");  ("L",".-.."); ("M","--");   ("N","-.");  ("O","---");
     ("P",".--."); ("Q","--.-"); ("R",".-.");  ("S","..."); ("T","-");
     ("U","..-");  ("V","...-"); ("W",".--");  ("X","-..-");("Y","-.--");
     ("Z","--..")]</pre>
<pre>let rec decode input =
    if input = "" then [""]
    else [ for c, code in codes when input.StartsWith(code)
           for rest in decode(input.Substring(String.length code))
           -&gt; c + rest ]</pre>
<p>As it can be seen the code is almost identical to the Python code.  Incidentally, I could not find a function equivalent to Python&#8217;s <code>startswith</code> method in the O&#8217;Caml standard library (without using regular expressions).  Fortunately F# came with one from the .NET library.</p>
<p>Much to my the surprise the compiled F# (running on Mono 1.2.4) is 4 times slower that the Python code.  I then rewrote the program to use sequence comprehensions:</p>
<pre>
let rec decode input =
    if input = "" then { -&gt; "" }
    else { for c, code in codes when input.StartsWith(code)
           for rest in decode(input.Substring(String.length code))
           -&gt; c + rest }</pre>
<p>This version runs faster, and uses only a constant amount of memory. Still the Python version is three and half times faster.</p>
<p>I then tried to run the programs on an other computer with Microsoft&#8217;s .NET implementation. This improved the F# running times a lot.  However, they are still 40% to 80% slower than the Python version.</p>
<p><img src="http://ken.friislarsen.net/blog/wp-content/fs-vs-python-morse.png" alt="Chart of F# vs Python on morse code decoding" /></p>
<p>My current guess is that Python is much better at handling strings than .NET.</p>
<p>The actual numbers:</p>
<table border="1">
<tr>
<th></th>
<th colspan="2">Linux, Mono</th>
<th colspan="2">Vista, MS .NET</th>
</tr>
<tr>
<td>Program</td>
<th>Time<br />
sec</th>
<th>Ratio</th>
<th>Time<br />
sec</th>
<th>Ratio</th>
</tr>
<tr>
<th><code>morse.py</code></th>
<td>7.94 ± 0.05</td>
<td>1</td>
<td>11.03 ± 0.03</td>
<td>1</td>
</tr>
<tr>
<th><code>morse.fs</code></th>
<td>33.07 ± 0.19</td>
<td>4.17</td>
<td>19.65 ± 0.33</td>
<td>1.78</td>
</tr>
<tr>
<th><code>morse-seq.fs</code></th>
<td>28.1 ± 0.59</td>
<td>3.54</td>
<td>16.12 ± 0.36</td>
<td>1.46</td>
</tr>
</table>
<p><strong>Update 2007-11-12 Added test files:</strong></p>
<ul>
<li>Python code: <a href="http://ken.friislarsen.net/tmp/morse-py.txt"><code>morse.py</code></a></li>
<li>F# code using list comprehensions: <a href="http://ken.friislarsen.net/tmp/morse.fs"><code>morse.fs</code></a></li>
<li>F# code using sequence comprehensions: <a href="http://ken.friislarsen.net/tmp/morse-seq.fs"><code>morse-seq.fs</code></a></li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://ken.friislarsen.net/blog/2007/11/09/decoding-morse-code-with-f-comprehensions/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>Morse Code Decoding With Python List Comprehensions</title>
		<link>http://ken.friislarsen.net/blog/2007/09/19/morse-code-decoding-with-python-list-comprehensions/</link>
		<comments>http://ken.friislarsen.net/blog/2007/09/19/morse-code-decoding-with-python-list-comprehensions/#comments</comments>
		<pubDate>Wed, 19 Sep 2007 20:16:44 +0000</pubDate>
		<dc:creator>Ken</dc:creator>
				<category><![CDATA[Coding]]></category>
		<category><![CDATA[General]]></category>
		<category><![CDATA[Python]]></category>

		<guid isPermaLink="false">http://ken.friislarsen.net/blog/2007/09/19/morse-code-decoding-with-python-list-comprehensions/</guid>
		<description><![CDATA[As a small exercise for getting up to speed with Python I decided to solve ruby quiz #121, which is to to write a function that finds all possible decodings of a string of Morse codes without letter- and word-separators.  Given the nature of the problem I decided to use python&#8217;s list comprehensions for [...]]]></description>
			<content:encoded><![CDATA[<p>As a small exercise for getting up to speed with <a href="http://python.org">Python</a> I decided to solve <a href="http://www.rubyquiz.com/quiz121.html">ruby quiz #121</a>, which is to to write a function that finds all possible decodings of a string of <a href="http://en.wikipedia.org/wiki/Morse_code">Morse codes</a> without letter- and word-separators.  Given the nature of the problem I decided to use python&#8217;s list comprehensions for the solution.</p>
<p>Without further ado here is the code I ended up with:</p>
<pre>#!/usr/bin/env python

import string

letters = [('A',".-"),   ('B',"-..."), ('C',"-.-."), ('D',"-.."), ('E',"."),
           ('F',"..-."), ('G',"--."),  ('H',"...."), ('I',".."),  ('J',".---"),
           ('K',"-.-"),  ('L',".-.."), ('M',"--"),   ('N',"-."),  ('O',"---"),
           ('P',".--."), ('Q',"--.-"), ('R',".-."),  ('S',"..."), ('T',"-"),
           ('U',"..-"),  ('V',"...-"), ('W',".--"),  ('X',"-..-"),('Y',"-.--"),
           ('Z',"--..")]

def decode(input):
    if input == "" :
        return [""]
    else:
        return [ letter + remaining
                 for letter, code in letters if input.startswith(code)
                 for remaining in decode(input[len(code):]) ]

# Some Testing code
def test(s, code):
    if s in decode(code):
        print code + " can be decoded as " + s
    else:
        print code + " can NOT be decoded as " + s

test("SOFIA", "...---..-....-")
test("SOPHIA", "...---..-....-")
test("EUGENIA", "...---..-....-")</pre>
<p>Interesting, my solution is rather similar to <a href="http://patricklogan.blogspot.com/2007/09/list-comprehensions.html">Patrick Logan&#8217;s Erlang solution</a>. And I find it simpler to understand than the <a href="http://www.haskell.org/haskellwiki/Haskell_Quiz/Morse_Code">Haskell solutions at the HaskellWiki.</a></p>
]]></content:encoded>
			<wfw:commentRss>http://ken.friislarsen.net/blog/2007/09/19/morse-code-decoding-with-python-list-comprehensions/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Recursive Descent Parsers in C#</title>
		<link>http://ken.friislarsen.net/blog/2006/09/08/recursive-descent-parsers-in-c/</link>
		<comments>http://ken.friislarsen.net/blog/2006/09/08/recursive-descent-parsers-in-c/#comments</comments>
		<pubDate>Fri, 08 Sep 2006 20:46:16 +0000</pubDate>
		<dc:creator>Ken</dc:creator>
				<category><![CDATA[C++]]></category>
		<category><![CDATA[Coding]]></category>
		<category><![CDATA[General]]></category>

		<guid isPermaLink="false">http://ken.friislarsen.net/blog/2006/09/08/recursive-decent-parsers-in-c/</guid>
		<description><![CDATA[Peter Sestoft and I have written a note about how to write scanners and parsers in C#. The note is based on earlier versions for SML and Java.
The note contains an thorough introduction to grammars on Backus&#8211;Naur form (BNF).  This includes a description of properties your grammar should have so that it can be [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://www.dina.kvl.dk/~sestoft">Peter Sestoft</a> and I have written a <a href="http://www.itu.dk/people/kfl/parsernotes.pdf">note about how to write scanners and parsers in C#</a>. The note is based on earlier versions for SML and Java.</p>
<p>The note contains an thorough introduction to grammars on Backus&#8211;Naur form (BNF).  This includes a description of properties your grammar should have so that it can be mechanically translated to a program.  And also some prescriptions about how to transform your grammar so that it has the desired properties.  In technical terms, the note describe how you can check that your grammar is an LL(1) grammar, and if not, some tricks that will usually transform it into one.</p>
<p>The parsers you write using our method are recursive descent parsers.  For the scanners, however, we just use and add-hoc method.  Both parsers and scanners makes good use of the .NET framework.  For instance, the scanners creates a token stream from a <code>TextReader</code>.  Hence, the scanners can be used to scan both files and strings.  Likewise, a token stream is represented as <code>IEnumerable&lt;Token&gt;</code> and scanners uses <code>yield</code> to create this token stream.  Thus, creating the token stream lazily.</p>
<p>To give an example, the simplest scanner presented in the note is the following scanner:</p>
<pre>
using TokenStream = System.Collections.Generic.IEnumerator&lt;Token&gt;;

class ZeroOneScan : IScanner {
  public TokenStream Scan(TextReader reader) {
    while ( reader.Peek() != -1 ) {
      if ( Char.IsWhiteSpace((char) reader.Peek()) )
        reader.Read();
      else
        switch(reader.Read()) {
        case '-': yield return Token.FromKind(Kind.SUB); break;
        case '0': yield return Token.FromKind(Kind.ZERO); break;
        case '1': yield return Token.FromKind(Kind.ONE); break;
        default: throw new ApplicationException("Illegal character");
        }
    }
    yield return Token.FromKind(Kind.EOF);
  }
}
</pre>
<p>I find this use of <code>yield</code> quite elegant.</p>
<p>Working with this note and getting my name on it has special meaning to me.  A precursor for SML was actually the note Peter used when he taught me for the first time many years ago (on my second semester at university). Over the years, I have returned to the note many times when I have needed to parse a small language that did not warrant the use of a parser generator, or when a generated parser would have been inconvenient to use because the text to be scanned did not come from a file stream (modern parser generators will not generate parsers with this problem).</p>
<p>The note ends a bit to early, in my opinion.  I would like extend the note to cover Extended BNF.  And I would also like to cover parser combinators.  Well, one day when time permits&#8230;</p>
]]></content:encoded>
			<wfw:commentRss>http://ken.friislarsen.net/blog/2006/09/08/recursive-descent-parsers-in-c/feed/</wfw:commentRss>
		<slash:comments>9</slash:comments>
		</item>
		<item>
		<title>ICFP Contest 2006, Team KFL</title>
		<link>http://ken.friislarsen.net/blog/2006/07/27/icfp-contest-2006-team-kfl/</link>
		<comments>http://ken.friislarsen.net/blog/2006/07/27/icfp-contest-2006-team-kfl/#comments</comments>
		<pubDate>Thu, 27 Jul 2006 11:37:39 +0000</pubDate>
		<dc:creator>Ken</dc:creator>
				<category><![CDATA[Fun]]></category>
		<category><![CDATA[General]]></category>
		<category><![CDATA[Personal]]></category>
		<category><![CDATA[SML]]></category>

		<guid isPermaLink="false">http://ken.friislarsen.net/blog/2006/07/27/icfp-contest-2006-team-kfl/</guid>
		<description><![CDATA[In 1967, during excavation for the construction of a new shopping center in Monroeville, Pennsylvania, workers uncovered a vault containing a cache of ancient scrolls. Most were severely damaged, but those that could be recovered confirmed the existence of a secret society long suspected to have been active in the region around the year 200 [...]]]></description>
			<content:encoded><![CDATA[<blockquote><p><em>In 1967, during excavation for the construction of a new shopping center in Monroeville, Pennsylvania, workers uncovered a vault containing a cache of ancient scrolls. Most were severely damaged, but those that could be recovered confirmed the existence of a secret society long suspected to have been active in the region around the year 200 BC.</em></p>
<p><em>Based on a translation of these documents, we now know that the society, the Cult of the Bound Variable, was devoted to the careful study of computation, over two millennia before the invention of the digital computer.<br />
<a href="http://www.boundvariable.org/task.shtml">&#8230;</a><br />
</em></p></blockquote>
<p>Like <a href="http://ken.friislarsen.net/blog/2005/06/27/team-what-a-summer-party-round-1/">last year</a> the prospects for my participation in the <a href="http://www.boundvariable.org">ICFP Contest</a> was not looking good.  None of my team mates from last year&#8217;s team seemed to be able to participate, and neither did I myself.  The weekend of the contest was packed with family business.  And on top of that, when the weekend arrived I was sick Friday night and Saturday.</p>
<p>However, Sunday evening I had some free time and I decided that I would take a crack a the contest just to see what it was about.  Judging from the discussion mailing-list it quite fun and interesting.  The first phase of the contest task was to implement a 14-instruction virtual machine called UM and when that was running you should use it for running the provided codex for the operating system UMIX.</p>
<p>So I registered my team KFL and started to implement my UM in SML.  The first thing I did was to implement an instruction decoder that could translate a 32-bit word into an SML datatype.  Then I wrote a function that read in a file of 32-bit words encoded in big-endian as four 8-bit words each.  And then <code>map</code>ed my decode function over the Vector of words.  For this task the SML Basis Library really shined:</p>
<pre>
fun readFile filename =
    let val dev = BinIO.openIn filename
        val all = BinIO.inputAll dev before BinIO.closeIn dev
        val words = Vector.tabulate(Word8Vector.length all div 4,
                                    fn i =&gt; Word32.fromLarge(PackWord32Big.subVec(all,i)))
    in  Vector.map decode words
    end</pre>
<p>Time spend: 1 hour.</p>
<p>Unfortunately, this did not work.  My decoding function failed after 1675 instructions or so, complaining about illegal instructions.  And indeed the 32-bit word it complained about did not seem to encode a legal instruction.  I tried to reimplement the conversion from 8-bit words to 32-bit words, in case <code>PackWord32Big</code> worked different than I thought.  But I still got the same error.  Thus, I gave up and went to bed.</p>
<p>Time spend: 2 hours.</p>
<p>Monday morning I had to see to some other things first, but then I had some time to spend on the contest.  Even after I had slept on the problem I still couldn&#8217;t figure out what was wrong.  So I asked my colleague <a href="http://itu.dk/people/panic">Arne</a> if he had 10 minutes to help me debug my program.  I explained him the problem, show him my code (actually my debug output, and then we looked at the codex in a hex-editor.  He confirmed that from my explanation, my program appeared to be working correctly, and it looked as if there was an illegal instruction in the codex, if all instructions really was encoded a single 32-word.  Hence, one or more of my assumptions had to wrong (is was easy to rule out that the codex was wrong, because more than a hundred teams were able to run the codex). Then it occurred to me, the codex was not required to only contain valid instructions, maybe the code would jump over damaged parts of the codex and part of the contest would be to repair the codex.  Thus, I changed my code to only decode instructions on demand, and kept the whole program as an array of 32-bit words.  Lo and behold  the machine was able to start running the codex!  However it failed in the self-check the codex performed. After some debugging I found one place where as I used the name of an register (registers in the UM is named by integers) as a value rather than using the value contained in the register. And now my UM was able to run the codex and the SANDmark (a debug and benchmark suite provided by the contest managers).</p>
<p>Time spend: 2 hours.</p>
<p>My first version ran the SANDmark in a bit more than 18 minutes (14 min user and 4 min sys) , 768 seconds user time according to MLton&#8217;s profiler.  Which was not to bad but I&#8217;d seen on the discussion list, that other participants had UMs that ran the SANDmark in a couple of minutes.  Thus, I decided to profile my UM to see where the time was spend.  To my surprise the top function in the profile was my decode function, a function that took a 32-bit word and translates it to an SML datatype.  Here are the first few lines of <code>decode</code> together with the helper function <code>standardRegs</code> that fetches out the register names:</p>
<pre>
fun standardRegs w =
    let open Word32
        val A = (w &lt;&lt; 0w23) &gt;&gt; 0w29
        val B = (w &lt;&lt; 0w26) &gt;&gt; 0w29
        val C = andb(w, 0w7)
    in (toInt A, toInt B, toInt C)
    end

fun decode w =
    let open Word32
        val opr = w &gt;&gt; 0w28
    in case opr of
           0w0  =&gt; CMove(standardRegs w)
         | 0w1  =&gt; ARead(standardRegs w)
         | 0w2  =&gt; AWrite(standardRegs w)
         ...</pre>
<p>And the top of my interpreter loop looked like this:</p>
<pre>
      while true do
             case spin() of
                 CMove(A,B,C) =&gt; if $C = 0w0 then ()
                                 else A &lt; - $B
               | ARead(A,B,C) =&gt; A &lt; - $$B sub (W32.toInt($C))
               | AWrite(A,B,C) =&gt; Array.update($$A, W32.toInt($B), $C)
               ...
</pre>
<p>Where <code>spin</code> is the function that reads the current word at the program counter, updates the program counter, decodes the word, and return the instruction.  But how could 19% of the time be spend in the <code>decode</code>.  I moved the call to decode from spin to my interpreter loop to aid the MLton optimisers:</p>
<pre>
      while true do
             case decode(spin()) of
</pre>
<p>This made the SANDmark 5 minutes faster wall clock time, that is 13 minutes.  Or in MLton profiler time 529 seconds. 30% improvement just for moving a function around.  Not bad.</p>
<p>Time spend: 30 minutes.</p>
<p>After this optimisation my UM was fast enough that I thought I&#8217;d try to solve some of the puzzles. So I logged into the UMIX OS using the guest account and started to poke around and collect points.  The first real puzzle was to fix a password cracker written in a weird Basic dialect that used roman numerals instead of decimal notation for integer literals (including for the line numbers).</p>
<p>Time spend: 1½ hour.  Collected points 230.</p>
<p>Then I had to go home, and while I cooked dinner (I was baking pita bread, and while the dough was rising I had time to hack) I was able to write an improved password cracker&#8212;in this weired roman numerals Basic: <a href="http://ken.friislarsen.net/blog/images/hack2.bas">hack2.bas</a>. This gained me an other 100 points, just before the contest ended (the contest ended at 18:00 in <a href="http://www.timeanddate.com/library/abbreviations/timezones/eu/cest.html">CEST</a>)</p>
<p>Time spend 45 min.  Collected points in total 330.</p>
<p>All in all not bad to make 330 points after spending only seven hours and 45 minutes of rather fragmented time.</p>
<p>After dinner I was able to gain an other 35 points by writing a list reversal program in a graphical 2D language: <a href="http://ken.friislarsen.net/blog/images/rev.2d">rev.2d</a>.  It took half an hour or so.</p>
<p>The setup for the contest was absolutely amazing and most entertaining.  My account of it here does not do it justice.  An incredible ammount of work must have gone into the preparation of it.  I&#8217;m looking forward for the final debriefing from the Contest Organizers.</p>
<p>Yesterday, I tried for fun to optimise my UM program a bit more.  Programs running on the UM are able to allocate and free arrays.  In my original implementation I used a ref to a functional Red-Black tree to keep track of the mapping from UM-pointers to arrays.  I know, not the best choice of data structure, but I was just trying to get a &#8220;got enough&#8221; UM up and running.  From the profile it was obvious that lots of time and memory was spend on keeping the Red-Black trees balanced.  Thus, I replaced this code with an array, and a free-list for reusing UM-pointers (32-bit words).  Thus, my code for managing the &#8220;heap&#8221; when from 12 lines of code (not counting the code in the Red-Black tree library) to 28 lines of code.  This small changed made the SANDmark run in 4 minutes wall clock(175 seconds of MLton profiler time) an improvement of almost 67%.  Looking at the profile, I could see that <code>decode</code> was again on top of the list (using 42% of the time).  Thus, I decided to inline <code>decode</code> and deforest the instruction datatype by hand.  This made my code 68 lines smaller, and the SANDmark ran in 2.50 minutes (134 seconds of MLton profiler time), 23% improvement. Almost four times faster than the UM I participated in the contest with.   Time spend 1½ hour.</p>
<ul>
<li>Code for the UM I participated with: <a href="http://ken.friislarsen.net/blog/images/um2.sml">um2.sml</a></li>
<li>Code with improve heap handling: <a href="http://ken.friislarsen.net/blog/images/um3.sml">um3.sml</a></li>
<li>Code with inlined decode function: <a href="http://ken.friislarsen.net/blog/images/um4.sml">um4.sml</a></li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://ken.friislarsen.net/blog/2006/07/27/icfp-contest-2006-team-kfl/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Theory of evolution</title>
		<link>http://ken.friislarsen.net/blog/2006/01/05/theory-of-evolution/</link>
		<comments>http://ken.friislarsen.net/blog/2006/01/05/theory-of-evolution/#comments</comments>
		<pubDate>Thu, 05 Jan 2006 16:15:03 +0000</pubDate>
		<dc:creator>Ken</dc:creator>
				<category><![CDATA[Fun]]></category>

		<guid isPermaLink="false">http://ken.friislarsen.net/blog/2006/01/05/theory-of-evolution/</guid>
		<description><![CDATA[There is no theory of evolution. Just a list of creatures Chuck Norris has allowed to live.
]]></description>
			<content:encoded><![CDATA[<p><i>There is no theory of evolution. Just a list of creatures Chuck Norris has allowed to live.</i></p>
]]></content:encoded>
			<wfw:commentRss>http://ken.friislarsen.net/blog/2006/01/05/theory-of-evolution/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Refactoring SML Quiz, Part 2</title>
		<link>http://ken.friislarsen.net/blog/2005/12/21/refactoring-sml-quiz-part-2/</link>
		<comments>http://ken.friislarsen.net/blog/2005/12/21/refactoring-sml-quiz-part-2/#comments</comments>
		<pubDate>Wed, 21 Dec 2005 21:41:43 +0000</pubDate>
		<dc:creator>Ken</dc:creator>
				<category><![CDATA[Coding]]></category>
		<category><![CDATA[General]]></category>
		<category><![CDATA[SML]]></category>

		<guid isPermaLink="false">http://ken.friislarsen.net/blog/2005/12/21/refactoring-sml-quiz-part-2/</guid>
		<description><![CDATA[The answer to yesterdays quiz is: Yes, types are necessary for lambda-lifting refactoring. Namely, if the lifted function contains an overloaded operator such as, e.g., +.
For example, given the program:

fun foo x =
    let fun add y = x + y
    in  add 5.0 end

where we want to [...]]]></description>
			<content:encoded><![CDATA[<p>The answer to yesterdays quiz is: Yes, types are necessary for lambda-lifting refactoring. Namely, if the lifted function contains an overloaded operator such as, e.g., <code>+</code>.</p>
<p>For example, given the program:</p>
<pre>
fun foo x =
    let fun add y = x + y
    in  add 5.0 end
</pre>
<p>where we want to lift the function <code>add</code>.  Our first attempt might be to transform the program into something like (refactoring is a source code to source code transformation):</p>
<pre>
fun add x y = x + y
fun foo x = add x 5.0
</pre>
<p>However, this might not compile with every SML compiler.  It depends on how much local context the compiler uses to resolve overloading.</p>
<p>Moscow ML compiles the transformed program above just fine.  But Moscow ML complains about the following version:</p>
<pre>
fun add x y = x + y<strong>;</strong>
fun foo x = add x 5.0
</pre>
<p>Notice the extra semi-colon after the declaration of <code>add</code>.</p>
<p><strong>Update 2005-12-22:</strong><br />
Just for good messure.  Here is one possible result of refactoring with necessary type information:</p>
<pre>
fun add (x : real) y = x + y<strong>;</strong>
fun foo x = add x 5.0
</pre>
<p>I believe that only captured variables needs to be typed.</p>
<p>Also note, that overloading is not the only problem.  It is possible to construct a similar example using records, but I&#8217;ll leave that to the reader (unless there is a popular and desperate demand, then I can provide an example).</p>
]]></content:encoded>
			<wfw:commentRss>http://ken.friislarsen.net/blog/2005/12/21/refactoring-sml-quiz-part-2/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Refactoring SML Quiz, Part 1</title>
		<link>http://ken.friislarsen.net/blog/2005/12/20/refactoring-sml-quiz/</link>
		<comments>http://ken.friislarsen.net/blog/2005/12/20/refactoring-sml-quiz/#comments</comments>
		<pubDate>Tue, 20 Dec 2005 21:55:26 +0000</pubDate>
		<dc:creator>Ken</dc:creator>
				<category><![CDATA[Coding]]></category>
		<category><![CDATA[General]]></category>
		<category><![CDATA[SML]]></category>

		<guid isPermaLink="false">http://ken.friislarsen.net/blog/2005/12/21/refactoring-sml-quiz/</guid>
		<description><![CDATA[Yesterday, I discussed with some students who are implementing an SML plug-in for eclipse, whether types are necessary for a lambda-lifting refactoring for SML.
So today&#8217;s quiz is simply: Are types necessary for lambda-lifting refactoring in SML? Why/Why not?
Remember, the refactoring works on valid SML programs, and after the transformation the program should still be valid.
Example:

fun [...]]]></description>
			<content:encoded><![CDATA[<p>Yesterday, I discussed with some students who are implementing an SML plug-in for eclipse, whether types are necessary for a lambda-lifting refactoring for SML.</p>
<p>So today&#8217;s quiz is simply: Are types necessary for lambda-lifting refactoring in SML? Why/Why not?</p>
<p>Remember, the refactoring works on valid SML programs, and after the transformation the program should still be valid.</p>
<p>Example:</p>
<pre>
fun foo x =
    let fun bar y = (x,y)
    in bar x end
</pre>
<p>is transformed/refactored to</p>
<pre>
fun bar x y = (x,y)
fun foo x = bar x x
</pre>
<p>I&#8217;ll give the answer tomorrow.</p>
]]></content:encoded>
			<wfw:commentRss>http://ken.friislarsen.net/blog/2005/12/20/refactoring-sml-quiz/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Implementing the generic IEnumerable interface</title>
		<link>http://ken.friislarsen.net/blog/2005/07/25/implementing-the-generic-ienumerable-interface/</link>
		<comments>http://ken.friislarsen.net/blog/2005/07/25/implementing-the-generic-ienumerable-interface/#comments</comments>
		<pubDate>Mon, 25 Jul 2005 13:05:46 +0000</pubDate>
		<dc:creator>Ken</dc:creator>
				<category><![CDATA[C++]]></category>
		<category><![CDATA[Coding]]></category>
		<category><![CDATA[General]]></category>

		<guid isPermaLink="false">http://ken.friislarsen.net/blog/2005/07/25/implementing-the-generic-ienumerable-interface/</guid>
		<description><![CDATA[Say you want to implement a class that implements the IEnumerable interface in C#.  Then you have two choices, either to implement the old-style non-generic IEnumerable interface or you can implements the generic IEnumerable&#60;T&#62; interface.  Given those choices we of course want to implement the new generic version of the interface.  Because [...]]]></description>
			<content:encoded><![CDATA[<p>Say you want to implement a class that implements the <code>IEnumerable</code> interface in C#.  Then you have two choices, either to implement the old-style non-generic <code>IEnumerable</code> interface or you can implements the generic <code>IEnumerable&lt;T&gt;</code> interface.  Given those choices we of course want to implement the new generic version of the interface.  Because otherwise lots of boxing and unboxing will happen when <code>T</code> is a value type, with the non-generic version you will not be able to conveniently use the <code>Current</code> property of your enumerator, and for general type-safety goodness.</p>
<p>Thus, you set out to implement the generic version.  For example, let say we want to implement a class that enumerates all the integers staring from a given offset.  First we might try this:</p>
<pre>
using System.Collections.Generic;
class Ints : IEnumerable&lt;int&gt; {
    private readonly int offset;
    public Ints(int o) { offset = o; }
    public IEnumerator&lt;int&gt; GetEnumerator() {
        int i = offset;
        while( true ) yield return i++;
    }
}
</pre>
<p>But then the compiler complains:</p>
<pre>
error CS0535: 'Ints' does not implement interface member 'System.Collections.IEnumerable.GetEnumerator()'
</pre>
<p>Thank you for letting us know nice compiler.  But we don&#8217;t want <code>Ints</code> to implement the non-generic interface.  We want it to implement the generic interface.</p>
<p>Reading up on the documentation will reveal that the generic interface inherits from the non-generic interface. What a wonderful design.  Thankfully we can make a general work-around for this design flaw in the library.  Just add a non-generic method that calls the generic method:</p>
<pre>
    System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() { return GetEnumerator(); }
</pre>
<p>Once the author of <a href="http://www.dina.kvl.dk/~sestoft/csharpprecisely/">my favorite C# book</a> returns from vacation. I&#8217;ll complain to him that the section about <code>IEnumerable</code> didn&#8217;t make it clear that if you want to implement the generic interface you also have to implement the non-generic interface.</p>
<p><b>Update:</b> It turns out that <a href="http://www.dina.kvl.dk/~sestoft/csharpprecisely/errata.html">the errata</a> to <a href="http://www.dina.kvl.dk/~sestoft/csharpprecisely">C# Precisely</a> already mentions this curriousity.</p>
]]></content:encoded>
			<wfw:commentRss>http://ken.friislarsen.net/blog/2005/07/25/implementing-the-generic-ienumerable-interface/feed/</wfw:commentRss>
		<slash:comments>8</slash:comments>
		</item>
	</channel>
</rss>
