<?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, 29 Sep 2011 12:16:51 +0000</lastBuildDate>
	<language>en-US</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.5.1</generator>
		<item>
		<title>Quality assessment of Haskell programs</title>
		<link>http://ken.friislarsen.net/blog/2011/09/28/quality-assessment-haskell-program/</link>
		<comments>http://ken.friislarsen.net/blog/2011/09/28/quality-assessment-haskell-program/#comments</comments>
		<pubDate>Wed, 28 Sep 2011 21:46:37 +0000</pubDate>
		<dc:creator>Ken</dc:creator>
				<category><![CDATA[Coding]]></category>
		<category><![CDATA[Haskell]]></category>

		<guid isPermaLink="false">http://ken.friislarsen.net/blog/?p=101</guid>
		<description><![CDATA[One of the greatest things about writing code in Haskell is the wonderful libraries (incidently, one of the worst things about writing code in Haskell is the libraries). In particular the libraries for assessing the quality of your own code. I’m especially found of: QuickCheck for a quick testing of the correctness of my code, [...]]]></description>
				<content:encoded><![CDATA[<p>One of the greatest things about writing code in Haskell is the wonderful libraries (incidently, one of the worst things about writing code in Haskell is the libraries). In particular the libraries for assessing the quality of your own code. I’m especially found of:</p>
<ul>
<li>
<p><a href="http://hackage.haskell.org/package/QuickCheck" title="QuickCheck">QuickCheck</a> for a quick testing of the correctness of my code, by letting me specify the <em>properties</em> I want to check, and taking care of generating random test-cases.</p>
</li>
<li>
<p><a href="http://hackage.haskell.org/package/criterion" title="Criterion">Criterion</a> for checking the time performance of my code in a statistical sound manner. Taking care of dealing with the garbage collector and such like.</p>
</li>
</ul>
<p>In this post I give a quick tour of how to use these libraries.</p>
<h3 id="getting-the-libraries">Getting the libraries</h3>
<p>Our first step is to install QuickCheck and Criterion:</p>
<pre><code>$ cabal install criterion quickcheck
</code></pre>
<p>Now we are ready to go.</p>
<h3 id="backstory">Backstory</h3>
<p>The standard list-based implementation of quicksort that you so often see, seems ripe for some optimisations:</p>
<pre><code>quicksort :: Ord a =&gt; [a] -&gt; [a]
quicksort []     = []
quicksort (p:xs) = quicksort lesser ++ [p] ++ quicksort greater
    where
        lesser  = [ x | x &lt;- xs, x &lt; p]
        greater = [ x | x &lt;- xs, x &gt;= p]
</code></pre>
<p>One obvious optimisation could be to only traverse <code>xs</code> once, when partitioning the elements into lesser and greater (and equal) than <code>p</code>. Here is one implementation that uses <code>foldl'</code> for maximum performance (we hope):</p>
<pre><code>kquicksort :: Ord a =&gt; [a] -&gt; [a]
kquicksort []     = []
kquicksort (p:xs) = kquicksort lesser ++ equal ++ kquicksort greater
    where
        (lesser,equal,greater) = foldl' part ([],[p],[]) xs
        part (l,e,g) x =
          case compare x p of
            LT -&gt; (x : l, e, g)
            GT -&gt; (l, e, x : g)
            EQ -&gt; (l, x : e, g)
</code></pre>
<h3 id="checking-some-properties">Checking some properties</h3>
<p>The basic usage of QuickCheck is to specify the properties you care about as ordinary Haskell functions, and then you use the <code>quickCheck</code> function to check the properties. In the following I use <code>QC</code> as the qualified name for values from the QuickCheck library.</p>
<p>The first property we want to check is that <code>kquicksort</code> returns a sorted result. To check this property we also define a helper predicate <code>sorted</code> that checks that a list is sorted:</p>
<pre><code>sorted :: Ord a =&gt; [a] -&gt; Bool
sorted (x1:x2:xs) = x1 &lt;= x2 &amp;&amp; (sorted $ x2:xs) 
sorted _          = True

prop_sorted :: Ord a =&gt; [a] -&gt; Bool
prop_sorted xs = sorted $ kquicksort xs
</code></pre>
<p>The next properties that we want to check could be that <code>kquicksort</code> is idempotent and if it is given an ordered argument it doesn’t mess it up:</p>
<pre><code>prop_idempotent :: Ord a =&gt; [a] -&gt; Bool
prop_idempotent xs = kquicksort xs == (kquicksort $ kquicksort xs)

prop_ordered :: Ord a =&gt; QC.OrderedList a -&gt; Bool
prop_ordered (QC.Ordered xs) = xs == kquicksort xs
</code></pre>
<p>For <code>prop_ordered</code> we use the type class <code>OrderedList</code> to specify that this property should only hold for arguments that are sorted.</p>
<p>Now we can use the <code>quickCheck</code> function to check all our properties:</p>
<pre><code>checkAll = do
  QC.quickCheck (prop_sorted :: [Int] -&gt; Bool)
  QC.quickCheck (prop_idempotent :: [Int] -&gt; Bool)
  QC.quickCheck (prop_ordered :: QC.OrderedList Int -&gt; Bool)
</code></pre>
<p>The type constraints on all the properties are necessary, because that is what makes overloading works, so that <code>quickCheck</code> can generate random test-cases. Alternatively we can give our properties a less general non-polymorphic type. However, by keeping the more general type for our properties we can check them for other types as well. For instance, we might want to check it for a custom type, like the following type <code>Colour</code>:</p>
<pre><code>data Colour = Red | Green | Blue
            deriving (Eq, Show, Ord)
</code></pre>
<p>Before we can use QuickCheck with the <code>Colour</code> type, we need to specify how to generate random values of this type. That is, make it an instance of the <code>Arbitrary</code> type class:</p>
<pre><code>instance QC.Arbitrary Colour where
  arbitrary = QC.elements [Red, Green, Blue]
</code></pre>
<p>Now, we can check the <code>prop_sorted</code> property by adding a simple type constraint:</p>
<pre><code>QC.quickCheck (prop_sorted :: [Colour] -&gt; Bool)
</code></pre>
<h3 id="checking-the-performance">Checking the performance</h3>
<p>Once we have convinced our-self the code could be correct, we can start worrying about performance. Thus, we turn to Criterion. When doing performance testing there are all sorts of gnarly details that can go wrong and ruin our experiments: we forget to force the lazy evaluation and thus measure the wrong thing, the running time of function we try to measure is to short to get a meaningful reading of with clock resolution on the computer we use, the garbage collector might introduce noise from one sampling into another, we might be using the computer for something while we run the experiments which could introduce noise, and so on.</p>
<p>In the following I use <code>C</code> as the qualified name for values from the Criterion library.</p>
<p>Criterion takes care of all these concerns, and just present us with a simple interface where the only thing we need to specify is which functions we want to run, on what data, and how much we want the result to be evaluated. Thus, to benchmark <code>kquicksort</code> on the list <code>[20, 10, 30]</code> and get a fully evaluated result, we first use the <code>nf</code> (for normal form) function from Criterion to get something <code>Benchmarkable</code>:</p>
<pre><code>C.nf kquicksort [20, 10, 30]
</code></pre>
<p>When we have something benchmarkable, we use the <code>bench</code> function to label it and turn it into a <code>Benchmark</code></p>
<pre><code>C.bench &quot;kquickcheck on short list&quot; $ C.nf kquicksort [20, 10, 30]
</code></pre>
<p>When we have a list of benchmark we can hand it over to <code>defaultMain</code> which makes an excellent <code>main</code> body for us that will allow us to configure our benchmark from the command-line without recompiling the program. Without further ado:</p>
<pre><code>makeList :: Int -&gt; [Int]
makeList n = QC.unGen (QC.vector n) (R.mkStdGen 42) 25

main :: IO()
main = do
  checkAll
  let sizes = [ 10000, 20000, 50000, 75000
              , 100000, 250000, 500000, 1000000]
  let inputs = [(n, makeList n) | n &lt;- sizes]
  let benchmarks = [ C.bench (name ++ show n) $ C.nf sort ns 
                   | (n, ns)      &lt;- inputs,
                     (name, sort) &lt;- [(&quot;quicksort &quot;,  quicksort),
                                      (&quot;kquicksort &quot;, kquicksort)]]
  C.defaultMain benchmarks
</code></pre>
<p>In the helper function <code>makeList</code> I have reused the generator framework from QuickCheck for generating some random test data for my benchmark. For simple integer lists as we have here it is a bit overkill, but for more complex input it can be nice.</p>
<h3 id="the-complete-program">The complete program</h3>
<p>If you want to find out if <code>kquicksort</code> really is faster than <code>quicksort</code> is here the complete program.</p>
<pre><code>import qualified Criterion.Main as C
import qualified Test.QuickCheck as QC
import qualified Test.QuickCheck.Gen as QC

import Data.List(foldl')
import qualified System.Random as R

quicksort :: Ord a =&gt; [a] -&gt; [a]
quicksort []     = []
quicksort (p:xs) = quicksort lesser ++ [p] ++ quicksort greater
    where
        lesser  = [ x | x &lt;- xs, x &lt; p]
        greater = [ x | x &lt;- xs, x &gt;= p]

kquicksort :: Ord a =&gt; [a] -&gt; [a]
kquicksort []     = []
kquicksort (p:xs) = kquicksort lesser ++ equal ++ kquicksort greater
    where
        (lesser,equal,greater) = foldl' part ([],[p],[]) xs
        part (l,e,g) x =
          case compare x p of
            LT -&gt; (x : l, e, g)
            GT -&gt; (l, e, x : g)
            EQ -&gt; (l, x : e, g)

sorted :: Ord a =&gt; [a] -&gt; Bool
sorted (x1:x2:xs) = x1 &lt;= x2 &amp;&amp; (sorted $ x2:xs) 
sorted _          = True

prop_sorted :: Ord a =&gt; [a] -&gt; Bool
prop_sorted xs = sorted $ kquicksort xs

prop_idempotent :: Ord a =&gt; [a] -&gt; Bool
prop_idempotent xs = kquicksort xs == (kquicksort $ kquicksort xs)

prop_ordered :: Ord a =&gt; QC.OrderedList a -&gt; Bool
prop_ordered (QC.Ordered xs) = xs == kquicksort xs

data Colour = Red | Green | Blue
            deriving (Eq, Show, Ord)

instance QC.Arbitrary Colour where
  arbitrary = QC.elements [Red, Green, Blue]

checkAll = do
  QC.quickCheck (prop_sorted :: [Int] -&gt; Bool)
  QC.quickCheck (prop_sorted :: [Colour] -&gt; Bool)
  QC.quickCheck (prop_idempotent :: [Int] -&gt; Bool)
  QC.quickCheck (prop_ordered :: QC.OrderedList Int -&gt; Bool)

makeList :: Int -&gt; [Int]
makeList n = QC.unGen (QC.vector n) (R.mkStdGen 42) 25

main :: IO()
main = do
  checkAll
  let sizes = [ 10000, 20000, 50000, 75000
              , 100000, 250000, 500000, 1000000]
  let inputs = [(n, makeList n) | n &lt;- sizes]
  let benchmarks = [ C.bench (name ++ show n) $ C.nf sort ns 
                   | (n, ns)      &lt;- inputs,
                     (name, sort) &lt;- [(&quot;quicksort &quot;,  quicksort),
                                      (&quot;kquicksort &quot;, kquicksort)]]
  C.defaultMain benchmarks
</code></pre>
<p>Compile it with the command-line</p>
<pre><code>$ ghc -O3 -W --make Quicksort.hs -o Quicksort
</code></pre>
]]></content:encoded>
			<wfw:commentRss>http://ken.friislarsen.net/blog/2011/09/28/quality-assessment-haskell-program/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<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 [...]]]></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://web.cecs.pdx.edu/~sheard/2008IcfpContest/">the eleventh ICFP programming contest</a>.</p>
<p>So far everything works like a charm, KVM can run <a href="http://web.cecs.pdx.edu/~sheard/2008IcfpContest/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[Coding]]></category>
		<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 show how to do it in F# instead. First using list comprehensions: let codes = [("A",".-"); ("B","-..."); ("C","-.-."); ("D","-.."); ("E","."); ("F","..-."); ("G","--."); ("H","...."); ("I",".."); ("J",".---"); ("K","-.-"); ("L",".-.."); ("M","--"); ("N","-."); ("O","---"); ("P",".--."); ("Q","--.-"); ("R",".-."); ("S","..."); ("T","-"); [...]]]></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 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 the [...]]]></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>1</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 your grammar is not an LL(1) grammar, we give your some tricks that will usually transform the grammar into an LL(1) grammar.</p>
<p>The parsers you write using our method are recursive descent parsers.  For the scanners, however, we just use an 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 note 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>10</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>3</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 lift the function add. [...]]]></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 [...]]]></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>
	</channel>
</rss>
