<?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"
	>

<channel>
	<title>therning.org/ magnus</title>
	<atom:link href="http://therning.org/magnus/feed" rel="self" type="application/rss+xml" />
	<link>http://therning.org/magnus</link>
	<description>Incoherent mumblings</description>
	<pubDate>Thu, 01 May 2008 21:31:11 +0000</pubDate>
	<generator>http://wordpress.org/?v=2.5.1</generator>
	<language>en</language>
			<item>
		<title>Dealing with life in Haskell</title>
		<link>http://therning.org/magnus/archives/349?&amp;owa_from=feed&amp;owa_sid=</link>
		<comments>http://therning.org/magnus/archives/349#comments</comments>
		<pubDate>Thu, 01 May 2008 21:31:11 +0000</pubDate>
		<dc:creator>Magnus</dc:creator>
		
		<category><![CDATA[Posts]]></category>

		<category><![CDATA[haskell]]></category>

		<category><![CDATA[linux]]></category>

		<category><![CDATA[perforce]]></category>

		<category><![CDATA[windows]]></category>

		<guid isPermaLink="false">http://therning.org/magnus/?p=349</guid>
		<description><![CDATA[I bet you have at least one silly little thing at work that, whenever it happens, you let out a sigh, maybe roll your eyes and whish that everyone would use a proper operating system.  A few days I finally decided to do something about one of my things like that.  At work, [...]]]></description>
			<content:encoded><![CDATA[<p>I bet you have at least one silly little thing at work that, whenever it happens, you let out a sigh, maybe roll your eyes and whish that everyone would use a proper operating system.  A few days I finally decided to do something about one of my things like that.  At work, Windows users will at times for some strange reason, manually create directories inside their work area, even though the directories actually are under version control.  Invariably they get the case wrong and due to an onfortunate combination of case insensitive filesystem on the client (Windows) and a version control system the cares about case (Perforce).  This results in files ending up all over the place even though they belong in the same directory.  The Windows users are none the wiser, they simply don&#8217;t see the problem.  Since I use a sane system (Linux) I do notice, and when I see it I sigh and roll my eyes.</p>

<p>Here&#8217;s my take on solving the problem:</p>

<pre><code>module Main where

import Control.Monad
import Data.Char
import System.Directory
import System.Environment
import System.FilePath
import System.IO.HVFS.Utils
import System.Posix.Files

data IFile = IFile
    { iFileIPath :: FilePath
    , iFileIName :: FilePath
    , iFileFull :: FilePath
    } deriving (Show)

toIFile :: FilePath -&gt; IFile
toIFile fp =  IFile path file fp
    where
        path = map toLower $ takeDirectory fp
        file = map toLower $ takeFileName fp

listFilesR :: FilePath -&gt; IO [IFile]
listFilesR path =
    recurseDir SystemFS path &gt;&gt;=
    filterM doesFileExist &gt;&gt;=
    mapM (return . toIFile)

linkFile :: FilePath -&gt; IFile -&gt; IO ()
linkFile dest ifile = do
        createDirectoryIfMissing True newDir
        createLink (iFileFull ifile) newFile
    where
        newDir = normalise $ dest &lt;/&gt; (iFileIPath ifile)
        newFile = newDir &lt;/&gt; (iFileIName ifile)

main :: IO ()
main = do
    args &lt;- getArgs
    listFilesR (args !! 0) &gt;&gt;= mapM_ (linkFile $ args !! 1)
</code></pre>

<p>Yes, this is the <a href="http://therning.org/magnus/archives/348">code</a> I wrote in Literate Haskell, but I think I&#8217;d better not disclose my rant against clueless Windows users publically <img src='http://therning.org/magnus/wp-includes/images/smilies/icon_wink.gif' alt=';-)' class='wp-smiley' /> </p>
]]></content:encoded>
			<wfw:commentRss>http://therning.org/magnus/archives/349/feed</wfw:commentRss>
		</item>
		<item>
		<title>Rubber and lhs?</title>
		<link>http://therning.org/magnus/archives/348?&amp;owa_from=feed&amp;owa_sid=</link>
		<comments>http://therning.org/magnus/archives/348#comments</comments>
		<pubDate>Tue, 29 Apr 2008 12:43:25 +0000</pubDate>
		<dc:creator>Magnus</dc:creator>
		
		<category><![CDATA[Posts]]></category>

		<category><![CDATA[haskell]]></category>

		<category><![CDATA[literate programming]]></category>

		<category><![CDATA[rubber]]></category>

		<guid isPermaLink="false">http://therning.org/magnus/?p=348</guid>
		<description><![CDATA[Another dear lazyweb post.

Yesterday night I hacked up a silly little tool for use at work.  Nothing spectaculari but I thought I&#8217;d try this Literate Haskell thing.  I decided to go the LaTeX route and created a .lhs file.  To my amazement rubber has a module for handling Literate Haskell, unfortunately it [...]]]></description>
			<content:encoded><![CDATA[<p>Another dear lazyweb post.</p>

<p>Yesterday night I hacked up a silly little tool for use at work.  Nothing spectacular<sup>i</sup> but I thought I&#8217;d try this <a href="http://www.haskell.org/haskellwiki/Literate_programming">Literate Haskell</a> thing.  I decided to go the LaTeX route and created a <code>.lhs</code> file.  To my amazement <a href="http://www.pps.jussieu.fr/~beffara/soft/rubber/">rubber</a> has a module for handling Literate Haskell, unfortunately it passes everything ending in <code>.lhs</code> through <a href="http://people.cs.uu.nl/andres/lhs2tex/">lhs2Tex</a>.  I didn&#8217;t really want to use lhs2Tex<sup>ii</sup> but I haven&#8217;t been able to find any way of changing rubber&#8217;s behaviour through its command line arguments.  What I&#8217;d like is a way to disable a module for a single invocation.  So, dear lazyweb, is there a way to do this from the command line?</p>

<p>So far I&#8217;ve worked around this by creating a symbolic link named <code>MyTool.tex</code> that points to the Haskell source, then I run rubber on the link.  Not to much of a hazzle, but it&#8217;d be nicer to pass an argument to rubber.</p>
<ol class="footnotes"><li id="footnote_0_348" class="footnote">I&#8217;ll post the source here shortly.</li><li id="footnote_1_348" class="footnote">I&#8217;ll probably have a closer look at it later but for now I wanted to keep things as easy as possible.</li></ol>]]></content:encoded>
			<wfw:commentRss>http://therning.org/magnus/archives/348/feed</wfw:commentRss>
		</item>
		<item>
		<title>Debian, lighttpd and MediaWiki</title>
		<link>http://therning.org/magnus/archives/347?&amp;owa_from=feed&amp;owa_sid=</link>
		<comments>http://therning.org/magnus/archives/347#comments</comments>
		<pubDate>Tue, 22 Apr 2008 19:16:23 +0000</pubDate>
		<dc:creator>Magnus</dc:creator>
		
		<category><![CDATA[Posts]]></category>

		<category><![CDATA[debian]]></category>

		<category><![CDATA[lighttpd]]></category>

		<category><![CDATA[mediawiki]]></category>

		<guid isPermaLink="false">http://therning.org/magnus/?p=347</guid>
		<description><![CDATA[I just went through the exercise of setting up MediaWiki on a Debian Etch box, but instead of serving it using the common choice of Apache I wanted to use lighttpd.  It seems the combination MediaWiki and Apache is well supported on Debian.  There was even an install-time question whether I wanted the [...]]]></description>
			<content:encoded><![CDATA[<p>I just went through the exercise of setting up <a href="http://www.mediawiki.org/">MediaWiki</a> on a Debian Etch box, but instead of serving it using the common choice of <a href="http://apache.org/">Apache</a> I wanted to use <a href="http://www.lighttpd.net/">lighttpd</a>.  It seems the combination MediaWiki and Apache is well supported on Debian.  There was even an install-time question whether I wanted the configuration files set up for me.  Well, it&#8217;s boring to follow the common path, right?</p>

<p>It seems the combination MediaWiki and Apache is well supported on Debian.  Luckily that doesn&#8217;t mean it&#8217;s difficult to serve it with lighttpd.  Here&#8217;s how I configured things, and luckily it all seems to work just fine <img src='http://therning.org/magnus/wp-includes/images/smilies/icon_wink.gif' alt=';-)' class='wp-smiley' /> </p>

<h3>Installation</h3>

<p>First off, I installed <code>mediawiki1.7</code>, <code>lighttpd</code>, <code>php5-cgi</code>, and <code>mysql-server</code>.  I made sure that aptitude only pulled in required packages and then I started un-choosing all Apache-related packages.  By the time you get to installing <a href="http://www.mysql.com/">MySQL</a> you&#8217;ll be asked for a root password, that is if your <code>debconf</code> is set to ask medium-level questions.</p>

<h3>Setting up MediaWiki</h3>

<p>The Debian package for MediaWiki creates a site in <code>/var/lib/mediawiki1.7</code> consisting mostly of symbolic links to the actual location of its files.  I kept lighttpd&#8217;s default document root of <code>/var/www</code> and linked the two by creating a symbolic link <code>/var/www/mw</code> pointing to the MediaWiki site (<code>/var/lib/mediawiki1.7</code>).</p>

<h3>Configuration of lighttpd</h3>

<p>First enable FastCGI by linking <code>/etc/lighttpd/conf-available/10-fastgi.conf</code> into <code>/etc/lighttpd/conf-enabled/</code>.  Then go in and change the <code>bin-path</code> to point to <code>/usr/bin/php5-cgi</code>.  To prepare for the MediaWiki configuration, enable <code>mod_rewrite</code> in <code>/etc/lighttpd/lighttpd.conf</code> and finally create the file <code>/etc/lighttpd/conf-enabled/20-mediawiki.conf</code> with the following contents:</p>

<pre><code>url.rewrite-once = (
    "^/$" =&gt; "/mw/index.php",
    "^/wiki/([^?]*)(?:\?(.*))?&#8221; =&gt; &#8220;/mw/index.php?title=$1&amp;$2&#8243;
  )
</code></pre>

<p>Now it&#8217;s time to restart lighttpd.</p>

<h3>Configuration of MediaWiki</h3>

<p>Point a browser to <em>http://your.server/mw/config/index.php</em> to configure the site settings.  When that&#8217;s done copy the file <code>/var/lib/mediawiki1.7/config/LocalSettings.php</code> one layer up.</p>

<p>That should be it!  Enjoy!</p>
]]></content:encoded>
			<wfw:commentRss>http://therning.org/magnus/archives/347/feed</wfw:commentRss>
		</item>
		<item>
		<title>Debian: pbuilder tip</title>
		<link>http://therning.org/magnus/archives/346?&amp;owa_from=feed&amp;owa_sid=</link>
		<comments>http://therning.org/magnus/archives/346#comments</comments>
		<pubDate>Mon, 21 Apr 2008 18:38:10 +0000</pubDate>
		<dc:creator>Magnus</dc:creator>
		
		<category><![CDATA[Posts]]></category>

		<category><![CDATA[debian]]></category>

		<category><![CDATA[pbuilder]]></category>

		<guid isPermaLink="false">http://therning.org/magnus/?p=346</guid>
		<description><![CDATA[I&#8217;m writing this mostly so that I&#8217;ll remember myself  

If pbuilder --create fails when building a base image for Sid then it&#8217;s worth trying to build a base image for the stable release and then upgrade to Sid afterwards.  The very manual way is pbuild --login --save-after-login.
]]></description>
			<content:encoded><![CDATA[<p>I&#8217;m writing this mostly so that I&#8217;ll remember myself <img src='http://therning.org/magnus/wp-includes/images/smilies/icon_smile.gif' alt=':-)' class='wp-smiley' /> </p>

<p>If <code>pbuilder --create</code> fails when building a base image for Sid then it&#8217;s worth trying to build a base image for the stable release and then upgrade to Sid afterwards.  The very manual way is <code>pbuild --login --save-after-login</code>.</p>
]]></content:encoded>
			<wfw:commentRss>http://therning.org/magnus/archives/346/feed</wfw:commentRss>
		</item>
		<item>
		<title>Packages for omnicodec and dataenc</title>
		<link>http://therning.org/magnus/archives/345?&amp;owa_from=feed&amp;owa_sid=</link>
		<comments>http://therning.org/magnus/archives/345#comments</comments>
		<pubDate>Mon, 21 Apr 2008 07:54:48 +0000</pubDate>
		<dc:creator>Magnus</dc:creator>
		
		<category><![CDATA[Posts]]></category>

		<guid isPermaLink="false">http://therning.org/magnus/?p=345</guid>
		<description><![CDATA[As promised I&#8217;ve now created Debian packages for omnicodec.  Since dataenc is a pre-requisite for building from source there are packages for it as well.

I&#8217;ve uploaded the source to Debian Mentors here and here.  As usual pre-built binaries are available from my own APT repo.
]]></description>
			<content:encoded><![CDATA[<p>As <a href="http://therning.org/magnus/archives/339">promised</a> I&#8217;ve now created Debian packages for omnicodec.  Since <a href="http://hackage.haskell.org/cgi-bin/hackage-scripts/package/dataenc">dataenc</a> is a pre-requisite for building from source there are packages for it as well.</p>

<p>I&#8217;ve uploaded the source to <a href="http://mentors.debian.net/">Debian Mentors</a> <a href="http://mentors.debian.net/cgi-bin/sponsor-pkglist?action=details;package=omnicodec">here</a> and <a href="http://mentors.debian.net/cgi-bin/sponsor-pkglist?action=details;package=haskell-dataenc">here</a>.  As usual pre-built binaries are available from <a href="http://therning.org/magnus/computer/apt-repo">my own APT repo</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://therning.org/magnus/archives/345/feed</wfw:commentRss>
		</item>
		<item>
		<title>ctypes and flexible (zero-length) arrays</title>
		<link>http://therning.org/magnus/archives/344?&amp;owa_from=feed&amp;owa_sid=</link>
		<comments>http://therning.org/magnus/archives/344#comments</comments>
		<pubDate>Wed, 09 Apr 2008 17:00:06 +0000</pubDate>
		<dc:creator>Magnus</dc:creator>
		
		<category><![CDATA[Posts]]></category>

		<category><![CDATA[C]]></category>

		<category><![CDATA[ctypes]]></category>

		<category><![CDATA[python]]></category>

		<guid isPermaLink="false">http://therning.org/magnus/?p=344</guid>
		<description><![CDATA[Dear lazyweb, I&#8217;ve been racking my brain trying to get information out of the following C struct in a nice way when using ctypes:

struct Foo
{
    unsigned int length;
    char name[];
};


I wrote a little C function to get instance of the struct easily into python:

struct Foo *
put_name(char *name)
{
   [...]]]></description>
			<content:encoded><![CDATA[<p>Dear lazyweb, I&#8217;ve been racking my brain trying to get information out of the following C struct in a nice way when using <a href="http://python.net/crew/theller/ctypes/">ctypes</a>:</p>

<pre><code>struct Foo
{
    unsigned int length;
    char name[];
};
</code></pre>

<p>I wrote a little C function to get instance of the struct easily into python:</p>

<pre><code>struct Foo *
put_name(char *name)
{
    struct Foo *foo = malloc(sizeof(struct Foo) + strlen(name));
    foo-&gt;length = strlen(name);
    memcpy(foo-&gt;name, name, foo-&gt;length);
    return(foo);
}
</code></pre>

<p>Now, how do I actually get the full contents of <code>Foo.name</code> in python?  The only way I could think of that actually works is to create a dummy-struct type in order to get the length out and then use it to dynamically create a new sub-class of <code>ctypes.Structure</code>, then create an instance based on the address of what was returned.  I think the following shows it pretty clearly:</p>

<pre><code>class FOO(Structure):
    _fields_ = [('length', c_uint), ('name', c_char * 0)]

liblib = cdll.LoadLibrary(&#8217;./_build/liblib.so&#8217;)
c_put_name = liblib.put_name
c_put_name.argtypes = [c_char_p]
c_put_name.restype = POINTER(FOO)

def put_name(str):
    f = c_put_name(str)
    K = type(&#8217;FOO%s&#8217; % f.contents.length, (Structure,),
                        {&#8217;_fields_&#8217; : [('length', c_uint), ('name', c_char * f.contents.length)]})
    return K.from_address(addressof(f.contents))
</code></pre>

<p>I still think there ought to be some other way that &#8216;feels&#8217; nicer.  I mean the use of “short arrays” (declared as here with <code>[]</code>, or zero size as supported by GCC, or the more portable array of size one) seems to be common enough to warrant some support from ctypes, right?</p>

<p>Any suggestions for improvements?</p>
]]></content:encoded>
			<wfw:commentRss>http://therning.org/magnus/archives/344/feed</wfw:commentRss>
		</item>
		<item>
		<title>Kid&#8217;s play with HTML in Haskell</title>
		<link>http://therning.org/magnus/archives/341?&amp;owa_from=feed&amp;owa_sid=</link>
		<comments>http://therning.org/magnus/archives/341#comments</comments>
		<pubDate>Sun, 30 Mar 2008 20:05:06 +0000</pubDate>
		<dc:creator>Magnus</dc:creator>
		
		<category><![CDATA[Posts]]></category>

		<category><![CDATA[audio webcasts]]></category>

		<category><![CDATA[haskell]]></category>

		<category><![CDATA[hxt]]></category>

		<guid isPermaLink="false">http://therning.org/magnus/archives/341</guid>
		<description><![CDATA[In my ever-continuing attempts to replace Python by Haskell as my language of first choice I&#8217;ve finally managed to dip a toe in the XML/HTML sea.  I decided to use the Haskell XML Toolkit (HXT) even though it&#8217;s not packaged for Debian (something I might look into doing one day).  HXT depends on [...]]]></description>
			<content:encoded><![CDATA[<p>In my ever-continuing attempts to replace Python by Haskell as my language of first choice I&#8217;ve finally managed to dip a toe in the XML/HTML sea.  I decided to use the <a href="http://www.fh-wedel.de/~si/HXmlToolbox/">Haskell XML Toolkit</a> (HXT) even though it&#8217;s not packaged for Debian (something I might look into doing one day).  HXT depends on <a href="http://www-users.cs.york.ac.uk/~ndm/tagsoup/">tagsoup</a> which also isn&#8217;t packaged for Debian.  Both packages install painlessly thanks to Cabal.</p>

<p>As the title suggests my itch wouldn&#8217;t require anything complicated, but when I&#8217;ve previously have looked at any Haskell XML library I&#8217;ve always shied away.  It all just looks so complicated.  It turns out it looks worse than it is, and of course the documentation is poor when it comes to simple, concrete examples with adequate explanations.  HXT would surely benefit from documentation at a level similar to what&#8217;s available for <a href="http://legacy.cs.uu.nl/daan/parsec.html">Parsec</a>.  I whish I were equipped to write it.</p>

<p>Anyway, this was my problem.  I&#8217;ve found an interesting audio webcast.  The team behind it has published around 90 episodes already and I&#8217;d like to listen to all of them.  Unfortunately their RSS feed doesn&#8217;t include all episodes so I can&#8217;t simply use the trusted <a href="http://software.complete.org/software/projects/show/hpodder">hpodder</a> to get all episodes.  After manually downloading about 20 of them I thought I&#8217;d better write some code to make it less labour-intensive.  Here&#8217;s the complete script:</p>

<pre><code>module Main where

import System.Environment
import Text.XML.HXT.Arrow

isMp3Link = (==) "3pm." . take 4 . reverse

myReadDoc = readDocument [(a_parse_html, "1"), (a_encoding, isoLatin1),
    (a_issue_warnings, "0"), (a_issue_errors, "0")]

myProc src = (runX $ myReadDoc src &gt;&gt;&gt; deep selectMp3Links &gt;&gt;&gt; getAttrValue &#8220;href&#8221;)
    &gt;&gt;= mapM_ putStrLn

selectMp3Links = hasName &#8220;a&#8221; &gt;&gt;&gt; hasAttrValue &#8220;href&#8221; isMp3Link

main = do
    [src] &lt;- getArgs
    myProc src
</code></pre>

<p>The thing that took by far the most time was finding out that <code>hasAttrValue</code> exists.  I&#8217;m currently downloading episodes using the following command line:</p>

<pre><code>curl -L $(for h in $(runhaskell get_mp3links.hs 'http://url.of.page/'); do \
    echo '-O' $h; done)
</code></pre>

<p>Yet another set of itches where Haskell has displaced Python as the utensil used for scratching. <img src='http://therning.org/magnus/wp-includes/images/smilies/icon_smile.gif' alt=':-)' class='wp-smiley' /> </p>
]]></content:encoded>
			<wfw:commentRss>http://therning.org/magnus/archives/341/feed</wfw:commentRss>
		</item>
		<item>
		<title>Saddle, two SDDL related tools</title>
		<link>http://therning.org/magnus/archives/340?&amp;owa_from=feed&amp;owa_sid=</link>
		<comments>http://therning.org/magnus/archives/340#comments</comments>
		<pubDate>Fri, 28 Mar 2008 00:09:02 +0000</pubDate>
		<dc:creator>Magnus</dc:creator>
		
		<category><![CDATA[Posts]]></category>

		<category><![CDATA[haskell]]></category>

		<category><![CDATA[security]]></category>

		<category><![CDATA[windows]]></category>

		<guid isPermaLink="false">http://therning.org/magnus/archives/340</guid>
		<description><![CDATA[I&#8217;ve just uploaded two small tools that makes it a little easier to deal with SDDL (Security Descriptor Description Language, this is a good resource for SDDL):


saddle-ex - “extract” the security descriptor for a number of different kinds of objects
saddle-pp - a pretty printer for an SDDL string


Full build instructions are included.  Download the [...]]]></description>
			<content:encoded><![CDATA[<p>I&#8217;ve just uploaded two small tools that makes it a little easier to deal with SDDL (Security Descriptor Description Language, this is a good <a href="http://msdn2.microsoft.com/en-us/library/aa379567.aspx">resource for SDDL</a>):</p>

<ol>
<li>saddle-ex - “extract” the security descriptor for a number of different kinds of objects</li>
<li>saddle-pp - a pretty printer for an SDDL string</li>
</ol>

<p>Full build instructions are included.  Download the archive <a href="http://therning.org/magnus_files/saddle/saddle-0.1.tar.gz">here</a>.</p>

<p>The tools are written (mostly) in Haskell and I&#8217;ll probably upload it all to <a href="http://hackage.haskell.org/packages/hackage.html">hackage</a> at some point in the future.  I&#8217;m holding out for a fix to <a href="http://hackage.haskell.org/trac/ghc/ticket/2097">ticket 2097</a> since a fix for it will allow me to add a third tool which I feel belong in the package.</p>

<p>Suggestions for improvements are always welcome, patches even more so <img src='http://therning.org/magnus/wp-includes/images/smilies/icon_smile.gif' alt=':-)' class='wp-smiley' /> </p>
]]></content:encoded>
			<wfw:commentRss>http://therning.org/magnus/archives/340/feed</wfw:commentRss>
		</item>
		<item>
		<title>Omnicodec released</title>
		<link>http://therning.org/magnus/archives/339?&amp;owa_from=feed&amp;owa_sid=</link>
		<comments>http://therning.org/magnus/archives/339#comments</comments>
		<pubDate>Wed, 19 Mar 2008 08:57:54 +0000</pubDate>
		<dc:creator>Magnus</dc:creator>
		
		<category><![CDATA[Posts]]></category>

		<category><![CDATA[haskell]]></category>

		<guid isPermaLink="false">http://therning.org/magnus/archives/339</guid>
		<description><![CDATA[Four days ago I uploaded omnicodec to Hackage.  It&#8217;s a collection of two simple command-line utilities for encoding and decoding data built on the dataenc package.  I&#8217;m planning on building a Debian package for it as soon as I find the time.
]]></description>
			<content:encoded><![CDATA[<p>Four days ago I uploaded <a href="http://hackage.haskell.org/cgi-bin/hackage-scripts/package/omnicodec">omnicodec</a> to Hackage.  It&#8217;s a collection of two simple command-line utilities for encoding and decoding data built on the <a href="http://hackage.haskell.org/cgi-bin/hackage-scripts/package/dataenc">dataenc</a> package.  I&#8217;m planning on building a Debian package for it as soon as I find the time.</p>
]]></content:encoded>
			<wfw:commentRss>http://therning.org/magnus/archives/339/feed</wfw:commentRss>
		</item>
		<item>
		<title>Haskell on Windows</title>
		<link>http://therning.org/magnus/archives/338?&amp;owa_from=feed&amp;owa_sid=</link>
		<comments>http://therning.org/magnus/archives/338#comments</comments>
		<pubDate>Sun, 17 Feb 2008 00:24:05 +0000</pubDate>
		<dc:creator>Magnus</dc:creator>
		
		<category><![CDATA[Posts]]></category>

		<category><![CDATA[cmake]]></category>

		<category><![CDATA[haskell]]></category>

		<category><![CDATA[visual studio express]]></category>

		<category><![CDATA[windows]]></category>

		<guid isPermaLink="false">http://therning.org/magnus/archives/338</guid>
		<description><![CDATA[Recently I&#8217;ve had reason to write a few tools for Windows.  Nothing complicated, and since there was nothing “mission critical” (there hardly ever is for me  ) I decided to try to write them in Haskell rather than Python or C/C++.  This post contains some sort of recollection of my experience so [...]]]></description>
			<content:encoded><![CDATA[<p>Recently I&#8217;ve had reason to write a few tools for Windows.  Nothing complicated, and since there was nothing “mission critical” (there hardly ever is for me <img src='http://therning.org/magnus/wp-includes/images/smilies/icon_smile.gif' alt=':-)' class='wp-smiley' /> ) I decided to try to write them in Haskell rather than Python or C/C++.  This post contains some sort of recollection of my experience so far.</p>

<p>First off I should probably disclose that I don&#8217;t particularly like Windows.  Besides feeling more at home on a Unix (Linux) system I find that Windows also upsets me on a very basic level.  If I spend a whole day at work in Windows I tend to go home more stressed and irritated than after a day in Linux.  Part of this is probably due to my familiarity with Linux.  My hope was that the combination of the immense joy of programming Haskell and my loath of the Windows platform I would end up with something that at least was bearable.  It turns out I did.</p>

<h3>My setup</h3>

<p>Besides installing the <a href="http://www.haskell.org/ghc/download.html">pre-built GHC</a> I also installed <a href="http://www.microsoft.com/express/">Visual Studio Express</a> more later to explain the need for it.  I don&#8217;t like the Visual Studio environment so I installed <a href="http://www.cmake.org/">CMake</a> and <a href="http://www.jedit.org/">jEdit</a><sup>i</sup>.  Last but not least I installed <a href="http://sourceforge.net/projects/console">Console</a>, it addresses the fact that Windows&#8217; “DOS-box” is an amazing piece of crap.</p>

<h3>FFI on Windows</h3>

<p>First, GHC comes with a number of Windows-specific modules and they cover an impressive number of the Win32 API functions.  The Win32 API is simply huge and one will sooner or later come find the need to add to what those modules offer.  Second, GHC is able to compile C code by delegation to <a href="http://www.mingw.org/">MinGW</a>, however MinGW doesn&#8217;t completely cover the Win32 API either and if one is unlucky MinGW isn&#8217;t enough for the task at hand.  Of course that&#8217;s exactly what happened to me.  So, I installed Visual Studio Express, but since I don&#8217;t like VS that much and I didn&#8217;t want VS solutions in my darcs repository I decided to use CMake to build a library that I then instruct GHC, through a Cabal file, to link with my Haskell code.  The end result is that building requires a few extra steps before the familiar <code>configure</code>/<code>build</code> sequence.  It works remarkably well really, and I&#8217;ll definately use that strategy again if I need to.</p>

<p>There is a benign warning thrown when linking the final executable though:</p>

<pre><code>Warning: .drectve `/manifestdependency:"type='win32' name='Microsoft.VC90.CRT'
version='9.0.21022.8' processorArchitecture='x86' publicKeyToken='1fc8b3b9a1e18e3b'"
/DEFAULTLIB:"uuid.lib" /DEFAULTLIB:"uuid.lib" /DEFAULTLIB:"MSVCRT" /DEFAULTLIB:"OLDNAMES" '
unrecognized
</code></pre>

<p>It seems that it might be possible to skip the extra steps in the future if <a href="http://hackage.haskell.org/trac/hackage/ticket/229">Cabal ticket #229</a> is addressed.</p>

<h3>Windows System modules</h3>

<p>Admittedly I haven&#8217;t been using much of the functionality in these modules, but it happens that the only function I needed had a bug that results in a segmentation fault, sometimes.  See <a href="http://hackage.haskell.org/trac/ghc/ticket/2097">GHC ticket #2097</a> for some details.  I guess this confirms my impression of most Haskell hackers being Linux/BSD/Unix users.</p>

<h3>Conclusions</h3>

<p>I won&#8217;t drop Haskell on Linux anytime soon, but I&#8217;ve found Haskell on Windows to be possible.  As I suspected when I started out, Haskell does make Windows somewhat easier to bear.</p>
<ol class="footnotes"><li id="footnote_0_338" class="footnote">ordinarily I would install <a href="http://www.vim.org/">Vim</a> but I thought I&#8217;d try out another editor.  Vim on Windows is somewhat “leaky”, i.e. it sometimes shows behaviour that betrays its Unix roots.</li></ol>]]></content:encoded>
			<wfw:commentRss>http://therning.org/magnus/archives/338/feed</wfw:commentRss>
		</item>
	</channel>
</rss>
