<?xml version="1.0" encoding="utf-8" ?>

<rss version="2.0" 
   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
   xmlns:admin="http://webns.net/mvcb/"
   xmlns:dc="http://purl.org/dc/elements/1.1/"
   xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
   xmlns:wfw="http://wellformedweb.org/CommentAPI/"
   xmlns:content="http://purl.org/rss/1.0/modules/content/"
   >
<channel>
    <title>nomeata’s mind shares - Haskell</title>
    <link>https://www.joachim-breitner.de/blog/</link>
    <description>Joachim Breitners Denkblogade</description>
    <dc:language>en</dc:language>
    <admin:errorReportsTo rdf:resource="mailto:mail@joachim-breitner.de" />
    <generator>Serendipity 1.5 - http://www.s9y.org/</generator>
    
    <image>
        <url>http://joachim-breitner.de/avatars/avatar_128.png</url>
        <title>RSS: nomeata’s mind shares - Haskell - Joachim Breitners Denkblogade</title>
        <link>https://www.joachim-breitner.de/blog/</link>
        <width>128</width>
        <height>128</height>
    </image>

<item>
    <title>Exploiting sharing in arbtt</title>
    <link>https://www.joachim-breitner.de/blog/archives/381-Exploiting-sharing-in-arbtt.html</link>
            <category>English</category>
            <category>Haskell</category>
    
    <comments>https://www.joachim-breitner.de/blog/archives/381-Exploiting-sharing-in-arbtt.html#comments</comments>
    <wfw:comment>https://www.joachim-breitner.de/blog/wfwcomment.php?cid=381</wfw:comment>

    <slash:comments>4</slash:comments>
    <wfw:commentRss>https://www.joachim-breitner.de/blog/rss.php?version=2.0&amp;type=comments&amp;cid=381</wfw:commentRss>
    

    <author>mail@joachim-breitner.de (nomeata)</author>
    <content:encoded>
    &lt;p&gt;My &lt;a href=&quot;http://www.joachim-breitner.de/projects#arbtt&quot;&gt;automatic rule-based time tracker&lt;/a&gt; (arbtt), which is written in Haskell, collects every minute a data sample consisting mainly of the list of currently open windows (window title and program name). Naturally, this log grows rather large. Since October of last year, I collected 70,000 samples. I already went &lt;a href=&quot;http://www.joachim-breitner.de/blog/archives/341-arbtt-goes-Binary.html&quot;&gt;from a text-based file format to a binary format&lt;/a&gt; using Data.Binary, which gave a big performance boost.&lt;br /&gt;&lt;/p&gt; 
&lt;p&gt;But by now, I was afraid that this is not enough. My log file is now 30MB large. Looking at the memory graph of gnome-panel, it is taking up more than half of my memory. When running arbtt-stats, the Haskell run time system reports 569 MB total memory in use and the command finishes after 28.5 seconds.&lt;/p&gt; 
&lt;p&gt;Naturally, the log file is highly redundant: Compressing it with bzip2 shrinks it to 1.6MB. But as I would like to preserve the ability to just append samples at the end, without having to read the file, I chose not just to add bzip2 or gzip compression. Rather, I am now exploiting a very obvious redundancy: Two adjacent samples usually list exactly the same windows, and a focus change only changes a flag. So now, when storing a string that is part of a sample, it will check if this string was already present in the previous sample and, in this case, just store the number of that string (one byte). Only if the string was not present it will write a zero byte and then the string. When reading the sample, the process is reversed.&lt;/p&gt; 
&lt;p&gt;This greatly reduces the file size: It is down to 6.2MB. It also improves the memory consumption, due to Haskell’s abilities with regard to sharing: When a reference to a string in a previous sample is read, then only one instance of this string is in memory, even if it occurs several times in the log. This brings the memory consumption down to 264 MB and the runtime to 17 seconds.&lt;/p&gt; 
&lt;p&gt;I released the changes as version 0.4.5.1 to &lt;a href=&quot;http://hackage.haskell.org/package/arbtt&quot;&gt;Hackage&lt;/a&gt;, &lt;a href=&quot;http://packages.debian.org/sid/arbtt&quot;&gt;Debian&lt;/a&gt; and as a &lt;a href=&quot;http://www.joachim-breitner.de/archive/arbtt/arbtt-setup-0.4.5.1.exe&quot;&gt;Windows installer&lt;/a&gt;. The log file is not automatically converted, but new samples will be written in the compressed format. If you want to convert your whole file, you have to stop arbtt-capture, run arbtt-recover, and then move the hopefully noticeable smaller &lt;a href=&quot;http://capture.log.recovered&quot;&gt;~/.arbtt/capture.log.recovered&lt;/a&gt;&amp;#160; to ~/.arbtt/capture.log.&lt;br /&gt;&lt;/p&gt; 
&lt;p&gt;The &lt;a href=&quot;http://darcs.nomeata.de/cgi-bin/darcsweb.cgi?r=arbtt;a=commitdiff;h=20100228205945-23c07-136eaf3cc7bd5c4e6f7b67f4d0cee1ac4433133e.gz&quot;&gt;required code changes&lt;/a&gt; were not too big. I somewhat isolated the relevant code in the &lt;a href=&quot;http://darcs.nomeata.de/arbtt/src/Data/Binary/StringRef.hs&quot;&gt;Data.Binary.StringRef&lt;/a&gt; module. Unfortunately, I have to use OverlappingInstances to be able to provide the special instance for String – is there a cleaner way (besides the trick used for the Show class)?&lt;br /&gt;&lt;/p&gt; 
    </content:encoded>

    <pubDate>Sun, 28 Feb 2010 23:04:48 +0100</pubDate>
    <guid isPermaLink="false">https://www.joachim-breitner.de/blog/archives/381-guid.html</guid>
    
</item>
<item>
    <title>Building arbtt for Windows</title>
    <link>https://www.joachim-breitner.de/blog/archives/358-Building-arbtt-for-Windows.html</link>
            <category>English</category>
            <category>Haskell</category>
    
    <comments>https://www.joachim-breitner.de/blog/archives/358-Building-arbtt-for-Windows.html#comments</comments>
    <wfw:comment>https://www.joachim-breitner.de/blog/wfwcomment.php?cid=358</wfw:comment>

    <slash:comments>6</slash:comments>
    <wfw:commentRss>https://www.joachim-breitner.de/blog/rss.php?version=2.0&amp;type=comments&amp;cid=358</wfw:commentRss>
    

    <author>mail@joachim-breitner.de (nomeata)</author>
    <content:encoded>
    &lt;p&gt;A friend of mine is interested in trying out the &lt;a href=&quot;http://www.joachim-breitner.de/projects#arbtt&quot;&gt;Automatic Rule Based Time-Tracker&lt;/a&gt; arbtt which I programmed. Unfortunately, he is using Windows and up to now, arbtt only worked on Linux. But as I wanted to check out Haskell’s cross-platform abilities for a while, this was a good opportunity to do so. I don’t have Windows installed myself (and did not plan to do so), so I did all this under &lt;a href=&quot;http://www.winehq.org/&quot;&gt;WINE&lt;/a&gt;, the Windows compatibility layer, which works very well: It takes only a few minutes to install the &lt;a href=&quot;http://hackage.haskell.org/platform/&quot;&gt;Haskell Platform&lt;/a&gt; for Windows and then I was able to run &lt;tt&gt;wine ghc --make&lt;/tt&gt; and &lt;tt&gt;cabal install&lt;/tt&gt;.&lt;/p&gt; 
&lt;p&gt;I played around with some simple programs and was surprised by these timings:&lt;/p&gt; 
&lt;pre&gt;$ rm *.o *.hi; ghc --make fourfours.hs ; time ./fourfours &amp;gt; /dev/null
[1 of 1] Compiling Main             ( fourfours.hs, fourfours.o )
Linking fourfours ...

real	0m1.909s
user	0m1.692s
sys	0m0.208s
$ rm *.o *.hi; wine ghc --make fourfours.hs ; time wine ./fourfours.exe &amp;gt; /dev/null
[1 of 1] Compiling Main             ( fourfours.hs, fourfours.o )
Linking fourfours.exe ...

real	0m1.631s
user	0m1.376s
sys	0m0.092s
&lt;/pre&gt; 
&lt;p&gt;So it is faster to run a compiled Haskell program on top of a compatibility layer than directly on Linux! The world is in order again, though, if optimization is enabled:&lt;/p&gt; 
&lt;pre&gt;$ rm *.o *.hi; ghc -O --make fourfours.hs ; time ./fourfours &amp;gt; /dev/null
[1 of 1] Compiling Main             ( fourfours.hs, fourfours.o )
Linking fourfours ...

real	0m0.981s
user	0m0.876s
sys	0m0.108s
$ rm *.o *.hi; wine ghc -O --make fourfours.hs ; time wine ./fourfours.exe &amp;gt; /dev/null
[1 of 1] Compiling Main             ( fourfours.hs, fourfours.o )
Linking fourfours.exe ...

real	0m1.270s
user	0m1.036s
sys	0m0.072s
&lt;/pre&gt; 
&lt;p&gt;Funny. Anyways, I wanted to port arbtt. The only platform-dependent part is the capture module that gathers the list of open Windows. The &lt;a href=&quot;http://hackage.haskell.org/package/Win32&quot;&gt;Win32&lt;/a&gt; package that comes with the Haskell Platform did not cover all the functions needed to do so, but creating additional function bindings is really easy with Haskell, as can be seen in the &lt;a href=&quot;http://darcs.nomeata.de/arbtt/src/Graphics/Win32/Window/Extra.hsc&quot;&gt;Graphics.Win32.Window.Extra&lt;/a&gt; module. I also replaced the locking code that prevents two instances of &lt;tt&gt;arbtt-capture&lt;/tt&gt; to run at the same time by equivalent code using Windows mutexes (module &lt;a href=&quot;http://darcs.nomeata.de/arbtt/src/System/Win32/Mutex.hsc&quot;&gt;System.Win32.Mutex&lt;/a&gt;). With these small changes and some CPP conditionals to make the code compile for either platform, the porting was done! Even accessing the files in &lt;tt&gt;~/.arbtt&lt;/tt&gt; works correctly on Windows, where it will look in the Application Data folder,  without changing the code, thanks to &lt;a href=&quot;http://hackage.haskell.org/packages/archive/directory/latest/doc/html/System-Directory.html#v%3AgetAppUserDataDirectory&quot;&gt;System.Directory.getAppUserDataDirectory&lt;/a&gt;.&lt;/p&gt; 
&lt;p&gt;But Windows users won’t like compiling software on their own. They won’t even like installing software by copying various files to certain directories. Therefore, I also had to create a Windows Installer. I picked &lt;a href=&quot;http://www.jrsoftware.org/isinfo.php&quot;&gt;Inno Setup&lt;/a&gt;, because it’s Free Software and seems to be simpler than NSIS. The installer puts the compiled &lt;tt&gt;.exe&lt;/tt&gt; files, the example &lt;tt&gt;categorize.cfg&lt;/tt&gt; and the HTML documentation in the right spot, adds icons to the Start Menu (“Edit categorize.cfg”, which fires up wordpad, a link to the documentation and the uninstaller), puts &lt;tt&gt;arbtt-capture&lt;/tt&gt; in the Autorun folder, puts the path to &lt;tt&gt;arbtt-stats&lt;/tt&gt; in the &lt;tt&gt;PATH&lt;/tt&gt; variable and starts &lt;tt&gt;arbtt-capture&lt;/tt&gt; at the end (the last three points being optional). Of course it undoes all this when removing the program again. I integrated the call to the Inno Setup installer into the usual ./&lt;a href=&quot;http://darcs.nomeata.de/arbtt/Setup.hs&quot;&gt;Setup&lt;/a&gt; build process of Haskell packages. Some more details of how to create the Windows installer are mentioned in the &lt;a href=&quot;http://darcs.nomeata.de/arbtt/README&quot;&gt;README&lt;/a&gt; file.&lt;/p&gt; 
&lt;p&gt;Now all this does not magically add a graphical user interface to arbtt, so users will still have to work with &lt;tt&gt;arbtt-stats&lt;/tt&gt; on the command line – even on Windows. If this is not a problem for you then you can fetch the latest installer from &lt;a href=&quot;http://www.joachim-breitner.de/projects#arbtt&quot;&gt;the arbtt homepage&lt;/a&gt;. And if you happen to become a serious user of arbtt on Windows and want to help maintaining the Windows port, I’ll gladly share some responsibilities.&lt;/p&gt; 
&lt;p&gt;I’m very satisfied with the process and the result and I’m happy to
know that I can offer some of my programs also to Windows users in the
future.It is also a big plus for Haskell – with Python, shipping a program for Windows users is likely more difficult. The next step will be providing gtk-based graphical Haskell applications for Windows, including a nice installer that ideally includes all dependencies (gtk etc.).&lt;br /&gt;&lt;/p&gt; 
    </content:encoded>

    <pubDate>Fri, 25 Dec 2009 19:48:00 +0100</pubDate>
    <guid isPermaLink="false">https://www.joachim-breitner.de/blog/archives/358-guid.html</guid>
    
</item>
<item>
    <title>Darcs Hacking Sprint: Mission Complete</title>
    <link>https://www.joachim-breitner.de/blog/archives/350-Darcs-Hacking-Sprint-Mission-Complete.html</link>
            <category>English</category>
            <category>Haskell</category>
    
    <comments>https://www.joachim-breitner.de/blog/archives/350-Darcs-Hacking-Sprint-Mission-Complete.html#comments</comments>
    <wfw:comment>https://www.joachim-breitner.de/blog/wfwcomment.php?cid=350</wfw:comment>

    <slash:comments>0</slash:comments>
    <wfw:commentRss>https://www.joachim-breitner.de/blog/rss.php?version=2.0&amp;type=comments&amp;cid=350</wfw:commentRss>
    

    <author>mail@joachim-breitner.de (nomeata)</author>
    <content:encoded>
    
&lt;p&gt;The &lt;a href=&quot;http://wiki.darcs.net/Sprints/2009-11&quot;&gt;darcs hacking sprint&lt;/a&gt; is slowly nearing its end. As planned, I have worked on integrating &lt;a href=&quot;http://darcswatch.nomeata.de/&quot;&gt;DarcsWatch&lt;/a&gt; and &lt;a href=&quot;http://bugs.darcs.net/&quot;&gt;bugs.darcs.net&lt;/a&gt;, and I am satisfied so far. From now on, if someone submits a Darcs patch to patches@darcs.net, the patch will also be tracked by DarcsWatch. DarcsWatch will display a link to the entry on bugs.darcs.net, and also add a comment to the bugtracker with a link to the patch on DarcsWatch. And eventually, if the patch is included in the darcs.net repository, DarcsWatch will change the state of the ticket to accepted, removing one step of work for the Darcs maintainers. Currently, it checks the state of the repository three times per hour, so expect a delay after you applied the patch to the repository before the state is updated.&lt;/p&gt; 
    </content:encoded>

    <pubDate>Sun, 15 Nov 2009 17:15:30 +0100</pubDate>
    <guid isPermaLink="false">https://www.joachim-breitner.de/blog/archives/350-guid.html</guid>
    
</item>
<item>
    <title>Arrived at the Darcs hacking sprint</title>
    <link>https://www.joachim-breitner.de/blog/archives/349-Arrived-at-the-Darcs-hacking-sprint.html</link>
            <category>English</category>
            <category>Haskell</category>
    
    <comments>https://www.joachim-breitner.de/blog/archives/349-Arrived-at-the-Darcs-hacking-sprint.html#comments</comments>
    <wfw:comment>https://www.joachim-breitner.de/blog/wfwcomment.php?cid=349</wfw:comment>

    <slash:comments>0</slash:comments>
    <wfw:commentRss>https://www.joachim-breitner.de/blog/rss.php?version=2.0&amp;type=comments&amp;cid=349</wfw:commentRss>
    

    <author>mail@joachim-breitner.de (nomeata)</author>
    <content:encoded>
    &lt;p&gt;Today, my alarm clock was set to 4:30, as I was going to Vienna, to attend the &lt;a href=&quot;http://wiki.darcs.net/Sprints/2009-11&quot;&gt;Darcs hacking sprint&lt;/a&gt;. I’ll be working on &lt;a href=&quot;http://darcswatch.nomeata.de/&quot;&gt;DarcsWatch&lt;/a&gt;, making it a bit more modular and hopefully integegrate it better into bug tracking systems (especially &lt;a href=&quot;http://roundup.sourceforge.net/&quot;&gt;roundup&lt;/a&gt;, as that’s &lt;a href=&quot;http://bugs.darcs.net/&quot;&gt;used by the Darcs team&lt;/a&gt;). On Monday, I’ll be a tourist until I leave in the evening. If any Debianers or Haskellers want to meet for keysigning or sightseeing, just drop me a mail!&lt;/p&gt;
 
    </content:encoded>

    <pubDate>Sat, 14 Nov 2009 09:32:05 +0100</pubDate>
    <guid isPermaLink="false">https://www.joachim-breitner.de/blog/archives/349-guid.html</guid>
    
</item>
<item>
    <title>arbtt: Now with Documentation</title>
    <link>https://www.joachim-breitner.de/blog/archives/342-arbtt-Now-with-Documentation.html</link>
            <category>English</category>
            <category>Haskell</category>
    
    <comments>https://www.joachim-breitner.de/blog/archives/342-arbtt-Now-with-Documentation.html#comments</comments>
    <wfw:comment>https://www.joachim-breitner.de/blog/wfwcomment.php?cid=342</wfw:comment>

    <slash:comments>0</slash:comments>
    <wfw:commentRss>https://www.joachim-breitner.de/blog/rss.php?version=2.0&amp;type=comments&amp;cid=342</wfw:commentRss>
    

    <author>mail@joachim-breitner.de (nomeata)</author>
    <content:encoded>
    
&lt;p&gt;Yesterday I did what Free Software authors supposedly don’t do. I wrote documentation. In fact, I had a relatively detailed README already, but I thought this would be a good opportunity to create a more elaborate documentation, using the ubiquitous  DocBook. You can read the &lt;a href=&quot;http://darcs.nomeata.de/arbtt/doc/users_guide/&quot;&gt;HTML documentation for arbtt&lt;/a&gt; online, where it’s automatically updated when I push to the &lt;a href=&quot;http://darcs.nomeata.de/arbtt&quot;&gt;darcs repository&lt;/a&gt;. You can see, I use the same CSS file that most Haskell-related DocBook documentation seems to use.&lt;/p&gt;&lt;p&gt;One motivation to use &lt;a href=&quot;http://www.docbook.org/&quot;&gt;DocBook&lt;/a&gt; was that I can extract manpages from it, which should be present if I package arbtt for Debian. I was about to complain that references from the manpages to other part of the documentation can not work sensibly, but using the &lt;a href=&quot;http://www.sagehill.net/docbookxsl/Profiling.html&quot;&gt;“profiling” feature&lt;/a&gt; of docbook-xsl, I can replace them by a textual reference to the user’s manual if the file is processed for manpage output. Have a look at &lt;a href=&quot;http://darcs.nomeata.de/cgi-bin/darcsweb.cgi?r=arbtt;a=commitdiff;h=20091011095133-23c07-07121a9d8fc2fa653342b367227a6d464e0dc437.gz&quot;&gt;my changes for that&lt;/a&gt; if you want to know how it works.&lt;/p&gt;&lt;p&gt;For some reason, the &amp;lt;refentry&amp;gt;-tags that make up the manpages are split to separate files when generating chunked HTML output, but they do not appear in the table of contents. You have to find a spot in the text where they are linked, as they are now in the section “&lt;a href=&quot;http://darcs.nomeata.de/arbtt/doc/users_guide/references.html&quot;&gt;Program references&lt;/a&gt;”, to find them. This is unfortunate, I expect that a few readers might miss this important part of the documentation. Am I doing something wrong?&lt;/p&gt;&lt;p&gt;For the configuration file, I put an &lt;a href=&quot;http://darcs.nomeata.de/arbtt/doc/users_guide/configuration.html#grammar&quot;&gt;EBNF-style grammar description&lt;/a&gt; in the documentation. There is a special &lt;a href=&quot;http://www.docbook.org/schemas/ebnf.html&quot;&gt;DocBook module&lt;/a&gt; for that, but I’m not satisfied with it. On the right hand side of production rules, it has only special support for nonterminals, but no tags to semantically mark up choice, repetition etc. I followed the lead found at the &lt;a href=&quot;http://yaml.org/spec/1.2/spec.dbk&quot;&gt;YAML specification&lt;/a&gt; and put &amp;lt;quote&amp;gt;-Tags around literal parts of the grammar, but this is not valid according to the DocBook DTD. Speaking of the DTD: I guess since the EBNF-stuff is just a module, the tag &amp;lt;productionset&amp;gt; is not a valid content of &amp;lt;figure&amp;gt;. So, if I choose to use the EBNF module in a sensible way, I will not have a valid DocBook file.&lt;/p&gt;&lt;p&gt;All in all, I am satisified with the result. Especially that nobody can say any more “I like your program, but I can’t contribute, because I don’t know Haskell”. Just improve the docs! :-)&lt;/p&gt; 
    </content:encoded>

    <pubDate>Sun, 11 Oct 2009 12:01:00 +0200</pubDate>
    <guid isPermaLink="false">https://www.joachim-breitner.de/blog/archives/342-guid.html</guid>
    
</item>
<item>
    <title>arbtt goes Binary</title>
    <link>https://www.joachim-breitner.de/blog/archives/341-arbtt-goes-Binary.html</link>
            <category>English</category>
            <category>Haskell</category>
    
    <comments>https://www.joachim-breitner.de/blog/archives/341-arbtt-goes-Binary.html#comments</comments>
    <wfw:comment>https://www.joachim-breitner.de/blog/wfwcomment.php?cid=341</wfw:comment>

    <slash:comments>6</slash:comments>
    <wfw:commentRss>https://www.joachim-breitner.de/blog/rss.php?version=2.0&amp;type=comments&amp;cid=341</wfw:commentRss>
    

    <author>mail@joachim-breitner.de (nomeata)</author>
    <content:encoded>
    
&lt;p&gt;Three weeks ago, I announced the &lt;a href=&quot;https://www.joachim-breitner.de/blog/archives/336-The-Automatic-Rule-Based-Time-Tracker.html&quot;&gt;automatic rule-based time tracker&lt;/a&gt; here, and it seems that there are actually users out there :-). Since then, it has recorded more than 240 hours of my computer’s uptime in about 15000 samples. Until now, this data was stored in a simple text file, one line per entry, and relying on Haskell’s Show/Read instances to do the serialization. Although not quite unexpected, this turned out to be a severe bottleneck: Already, it takes more than 25 seconds to parse the log file on my computer.&lt;/p&gt;&lt;p&gt;Following an advice given to me on the #haskell IRC channel, I switched to a binary representation of the data, using the very nice &lt;a href=&quot;http://code.haskell.org/binary/&quot;&gt;Data.Binary&lt;/a&gt; module. The capture program will automatically detect if the log file is in the old format, move it away and convert the entries to binary data. And voilà, the statistics program evalutes my data in about two seconds! This should be fast enough for quite a while, I hope.&lt;/p&gt;&lt;p&gt;In my binary instances, which you can find in &lt;a href=&quot;http://darcs.nomeata.de/arbtt/src/Data.hs&quot;&gt;Data.hs&lt;/a&gt;, I prepended a version tag to each entry. This hopefully allows me to add more fields to the log file later, while still being able to parse the old data directly and without conversion. To still be able to manually inspect the recorded data, the program arbtt-dump was added to the package. The new version is uploaded to &lt;a href=&quot;http://hackage.haskell.org/package/arbtt&quot;&gt;hackage&lt;/a&gt; as 0.3.0.&lt;/p&gt;&lt;p&gt;One thing still worries me: With the old format, I could easily throw away unparseable lines in the log file (e.g. from a partial write) and still read the rest of it. With the new code, there is no such robustness: If the file breaks somewhere, it will be unreadable in its whole, or at least to the broken point. I’m not sure what to do about that problem, but given the very low number of bytes written each time, I hope that it will just not happen.&lt;/p&gt;&lt;p /&gt; 
    </content:encoded>

    <pubDate>Sun, 04 Oct 2009 13:09:00 +0200</pubDate>
    <guid isPermaLink="false">https://www.joachim-breitner.de/blog/archives/341-guid.html</guid>
    
</item>
<item>
    <title>GPN8: 50% complete</title>
    <link>https://www.joachim-breitner.de/blog/archives/331-GPN8-50%25-complete.html</link>
            <category>Deutsch</category>
            <category>Haskell</category>
    
    <comments>https://www.joachim-breitner.de/blog/archives/331-GPN8-50%25-complete.html#comments</comments>
    <wfw:comment>https://www.joachim-breitner.de/blog/wfwcomment.php?cid=331</wfw:comment>

    <slash:comments>0</slash:comments>
    <wfw:commentRss>https://www.joachim-breitner.de/blog/rss.php?version=2.0&amp;type=comments&amp;cid=331</wfw:commentRss>
    

    <author>mail@joachim-breitner.de (nomeata)</author>
    <content:encoded>
    
&lt;p&gt;Die &lt;a href=&quot;http://entropia.de/wiki/GPN8&quot;&gt;achte GulaschProgrammierNacht&lt;/a&gt; des Karlsruher &lt;a href=&quot;http://entropia.de/wiki/Hauptseite&quot;&gt;Entropia e.V.&lt;/a&gt; ist hat so langsam Halbzeit, und ich will ein wenig berichten:&lt;/p&gt;&lt;p&gt;Gestern Abend war der erste Vortrag meine Einführung in das Programmierspiel &lt;a href=&quot;http://entropia.de/wiki/L-seed&quot;&gt;L-seed&lt;/a&gt; (mit in Kürze zusammengeschriebene &lt;a href=&quot;http://git.nomeata.de/?p=L-seed.git;a=blob_plain;f=doc/GPN-Intro/Intro.pdf;hb=HEAD&quot;&gt;Folien&lt;/a&gt;). Ich hatte ja eigentlich keine großen Hoffnungen, dass das Spiel großen Zuspruch erfährt, sind die Möglichkeiten darin ja eher beschränkt und die Ausgabe nicht besonders schick, aber da habe ich mich getäuscht: Seitdem kurz nach dem Vortrag das Netzwerk lief und der Server erreichbar war, wurden ununterbrochen und die Nacht durch Pflanzen programmiert!  Etwa 30 Pflanzen laufen gerade, von vermutlich fast so vielen Spielern. Vor lauter Vorschlägen, Wünsche und Fragen kam ich kaum mehr zum weiterprogrammieren. Immerhin konnte ich die schlimmsten Fehler noch ausbügeln (etwa, dass man mit sehr kurzen Pflanzen sich beliebig schnell vermehren konnte, oder dass vertikale Pflanzen zu stark sind).&lt;/p&gt;&lt;p&gt;Inzwischen wird auch regelmäßig der &lt;a href=&quot;http://lseed/screen.png&quot;&gt;Zustand des Spiels&lt;/a&gt; als Bilddatei rausgeschrieben (natürlich nur während der GPN erreichbar).&lt;/p&gt;&lt;p&gt;Die ersten kämpfen sich jetzt durch die Installation der Haskell-Toolchain, unter Debian momentan wegen &lt;a href=&quot;http://ftp-master.debian.org/new/haskell-parsec2_2.1.0.1-1.html&quot;&gt;Paketen in NEW&lt;/a&gt; stark erschwert . Vielleicht kommen bald auch noch Patches!&lt;/p&gt;&lt;p&gt;Wenn Ihr momentan nicht auf den &lt;a href=&quot;http://lseed.gpn.entropia.de/&quot;&gt;Lseed-Server&lt;/a&gt; zugreifen könnt, dann kann das am „Routing-Loch“ liegen: Teile des Internets sind von hier aus nicht erreichbar, weil wohl manche Routingtabellen nicht aktualisiert wurden. Leider auch mein Server, so dass dies hier nur über Umwege schreiben kann...&lt;/p&gt; 
    </content:encoded>

    <pubDate>Sat, 27 Jun 2009 11:19:48 +0200</pubDate>
    <guid isPermaLink="false">https://www.joachim-breitner.de/blog/archives/331-guid.html</guid>
    
</item>
<item>
    <title>Introducing L-seed</title>
    <link>https://www.joachim-breitner.de/blog/archives/330-Introducing-L-seed.html</link>
            <category>English</category>
            <category>Haskell</category>
    
    <comments>https://www.joachim-breitner.de/blog/archives/330-Introducing-L-seed.html#comments</comments>
    <wfw:comment>https://www.joachim-breitner.de/blog/wfwcomment.php?cid=330</wfw:comment>

    <slash:comments>0</slash:comments>
    <wfw:commentRss>https://www.joachim-breitner.de/blog/rss.php?version=2.0&amp;type=comments&amp;cid=330</wfw:commentRss>
    

    <author>mail@joachim-breitner.de (nomeata)</author>
    <content:encoded>
    
&lt;p&gt;In two weeks, the eighth „&lt;a href=&quot;http://entropia.de/wiki/GPN8&quot;&gt;Gulasch-Programmier-Nacht&lt;/a&gt;“ will be held in Karlsruhe, a yearly geek event  by the &lt;a href=&quot;http://entropia.de/&quot;&gt;Entropia e.V&lt;/a&gt;, which is the local &lt;a href=&quot;http://ccc.de/&quot;&gt;CCC&lt;/a&gt; club. It will, as usually, offer a lot of interesting talks and events. One of my personal highlights have always been the programming games: Games, where you write your own code to compete against others, while the playing field is projected in the hacking area. The last few years, dividuum has done a great job providing these (as regular readers of my blog might &lt;a href=&quot;https://www.joachim-breitner.de/blog/archives/295-GPN-7-Resume.html&quot;&gt;remember&lt;/a&gt;).&lt;/p&gt;&lt;p&gt;This year, I’m trying to follow in his footsteps and will provide the programming game, called „&lt;a href=&quot;http://entropia.de/wiki/L-seed&quot;&gt;L-seed&lt;/a&gt;“. This blog post is an introduction (and a call for contribution, at the bottom of the post :-))&lt;/p&gt;&lt;h3&gt;The idea&lt;/h3&gt;&lt;p&gt;The participants will write code (the „genome“) that describes how plants (the biological type, not the industrial) will grow. The plants will grow simultaneously on the screen (the „garden“), will compete for light and will multiply. The players can not change the code of a growing plant, but they do have the chance to update their code for the next generation – when a plant drops a seed, it will run the newest code. All in all, the game aims to be slowly paced and relaxing, something to just watch for a while and something that does not need constant attention by the players. The score is based on the total amount of biomass produced, but I expect (and hope) that some players will aim for the most beautiful or weirdest shapes.&lt;/p&gt;&lt;h3&gt;The plant code&lt;/h3&gt;&lt;p&gt;In contrast to the previous years, this year’s game will not allow player to use a full-fledged Turing-complete programming language, but a rather minimalistic rule based language to describe the plant’s growth. Especially, it will be hard to coordinate different branches of the same plant: Information mostly flows from the leaves to the root, and not the other direction.&lt;/p&gt;&lt;p&gt;The simplest plant is based on this code:&lt;/p&gt;&lt;pre&gt;// This is the trivial plant, which just grows and grows&lt;br /&gt;RULE &amp;quot;Very simple Rule&amp;quot;&lt;br /&gt;GROW BY 1&lt;/pre&gt;&lt;p&gt;You can see that each rule has a name (which is purely informational), and an action which tells the current branch to, well, grow by one. The syntax allows for Java-style comments, whitespace and newlines are insignificant and the reserved words are case-insensitive. The result will be a plant that just grows straight up, for ever and ever. A more complex rule might be this:&lt;/p&gt;&lt;pre&gt;&lt;img vspace=&quot;2&quot; hspace=&quot;2&quot; border=&quot;0&quot; src=&quot;http://www.joachim-breitner.de/various/L-seed-christmas-tree.png&quot; style=&quot;float: right;&quot; /&gt;RULE &amp;quot;Start&amp;quot;&lt;br /&gt;WHEN Length &amp;lt;= 0&lt;br /&gt;GROW BY 1&lt;br /&gt;SET TAG = &amp;quot;Root1&amp;quot;&lt;br /&gt;&lt;br /&gt;RULE &amp;quot;Story 1&amp;quot;&lt;br /&gt;WHEN TAG = &amp;quot;Root1&amp;quot;&lt;br /&gt;// No Percentage means 100%&lt;br /&gt;BRANCH ANGLE = 70°, LENGTH = 2, Tag = &amp;quot;&amp;quot;&lt;br /&gt;       ANGLE = -70°, LENGTH = 2, Tag = &amp;quot;&amp;quot;&lt;br /&gt;       ANGLE = 0°, LENGTH = 1, TAG = &amp;quot;Root2&amp;quot;&lt;br /&gt;SET TAG = &amp;quot;&amp;quot;&lt;br /&gt;&lt;br /&gt;RULE &amp;quot;Story 2&amp;quot;&lt;br /&gt;WHEN TAG = &amp;quot;Root2&amp;quot;&lt;br /&gt;BRANCH AT 100% ANGLE = 70°, LENGTH = 1.5, Tag = &amp;quot;&amp;quot;&lt;br /&gt;               ANGLE = -70°, LENGTH = 1.5, Tag = &amp;quot;&amp;quot;&lt;br /&gt;               ANGLE = 0°, LENGTH = 1, TAG = &amp;quot;Root3&amp;quot;&lt;br /&gt;SET TAG = &amp;quot;&amp;quot;&lt;br /&gt;&lt;br /&gt;RULE &amp;quot;Story 3&amp;quot;&lt;br /&gt;WHEN TAG = &amp;quot;Root3&amp;quot;&lt;br /&gt;BRANCH AT 100% ANGLE = 70°, LENGTH = 1, Tag = &amp;quot;&amp;quot;&lt;br /&gt;               ANGLE = -70°, LENGTH = 1, Tag = &amp;quot;&amp;quot;&lt;br /&gt;               ANGLE = 0°, LENGTH = 1, TAG = &amp;quot;Root4&amp;quot;&lt;br /&gt;SET TAG = &amp;quot;&amp;quot;&lt;br /&gt;&lt;br /&gt;RULE &amp;quot;Story 4&amp;quot;&lt;br /&gt;WHEN TAG = &amp;quot;Root4&amp;quot;&lt;br /&gt;BRANCH AT 100% ANGLE = 70°, LENGTH = 0.5, Tag = &amp;quot;&amp;quot;&lt;br /&gt;               ANGLE = -70°, LENGTH = 0.5, Tag = &amp;quot;&amp;quot;&lt;br /&gt;               ANGLE = 0°, LENGTH = 0.5, Tag = &amp;quot;Tip&amp;quot;&lt;br /&gt;SET TAG = &amp;quot;&amp;quot;&lt;br /&gt;&lt;br /&gt;RULE &amp;quot;Star&amp;quot;&lt;br /&gt;WHEN TAG = &amp;quot;Tip&amp;quot;&lt;br /&gt;Blossom&lt;/pre&gt;&lt;p&gt;I added a picture with the resulting tree. The yellow blob at the top is a not-yet-polished rendering of a blossom. At the right, there is already the first offspring of the plant. One thing to keep in mind while writing a genome is that rules are applied to single branches, and not the whole plant. The program will, for each branch individually, check which rules apply and choose one.  I’ll skip a detailed description of the syntax here, eventually you will find proper documentation on the entropia wiki page. You can find &lt;a href=&quot;http://git.nomeata.de/?p=L-seed.git;a=tree;f=examples&quot;&gt;more examples&lt;/a&gt; in the source repository.&lt;/p&gt;&lt;h3&gt;The gameplay&lt;/h3&gt;&lt;p&gt;The players will register at a website providing the usual CRUD functionality for their code, with integrated syntax checking. They can have more than one code at the same time, but only one can be marked as „active.“ The program actually serving the projector will regularly fetch the active code and run a around (called „season“) of the game. Whenever a new seed grows, the program will get the possibly updated active code of that user and use that. A season will probably last for a fixed amount of time, and at the end the total biomass accumulated by each player is added up and written back to the database.&lt;/p&gt;&lt;h3&gt;The game code&lt;/h3&gt;&lt;p&gt;You can fetch the source code from my &lt;a href=&quot;http://git.nomeata.de/?p=L-seed.git;a=summary&quot;&gt;git repository&lt;/a&gt; and browse the &lt;a href=&quot;http://entropia.de/~nomeata/L-seed-doc/&quot;&gt;haddock documentation&lt;/a&gt;. Unsurprisingly, it is written in Haskell. To compile it yourself, you will need the GHC Haskell compiler, parsec version 3 and for the visualization the gtk2hs package, all of which are packaged in Debian unstable. The main.hs is the interesting program. You pass it one or more plants as an argument, and it will start the simulation. If it’s too slow for test runs, then reduce the &lt;a href=&quot;http://entropia.de/~nomeata/L-seed-doc/Lseed-Constants.html#v%3AdayLength&quot;&gt;dayLength&lt;/a&gt; variable in Lseed/Constants.hs. If you have trouble getting it to run, just talk to me.&lt;/p&gt;&lt;h3&gt;The call for help&lt;/h3&gt;&lt;p&gt;As you can see in the picture above, the graphical output is not very aesthetic. I am no artist, and I don’t pretend to be one. So, if you think you have the right touch, maybe know OpenGL and a bit of Haskell, I’d be very grateful if you make it look better. The UI interface is quite simple: You need to have a module that returns an &lt;a href=&quot;http://entropia.de/~nomeata/L-seed-doc/Lseed-Data.html#t%3AObserver&quot;&gt;Observer&lt;/a&gt; value, which contains a few callbacks for various situations. The code in &lt;a href=&quot;http://git.nomeata.de/?p=L-seed.git;a=blob;f=src/Lseed/Renderer/Cairo.hs;hb=HEAD&quot;&gt;Lseed/Renderer/Cairo.hs&lt;/a&gt; can of course be used as a guideline. I’m suggesting OpenGL because my code is not only ugly, it is also too slow very quickly. If you need any help, just contact me by mail or jabber.&lt;/p&gt;&lt;p&gt;I’m also interested in comments about the game balance, and the expressiveness of the programming language. If you play around with the code and discover that there are missing features in the language, or that your plants grow too fast or too slow, or when you discover bugs, please also tell me.&lt;/p&gt;&lt;h3&gt;Thanks&lt;/h3&gt;&lt;p&gt;L-seed is based on an &lt;a href=&quot;https://www.joachim-breitner.de/blog/archives/129-Fixe-Idee-Warfeu.html&quot;&gt;old idea of mine&lt;/a&gt;, advanced together with Cupe, Sven Hecht is programming the web interface, and Lay is testing the game and bugs me about it to keep the motivation going.&lt;/p&gt;&lt;p&gt;&lt;b&gt;Update&lt;/b&gt;: I uploaded the package to &lt;a href=&quot;http://hackage.haskell.org/package/L-seed&quot;&gt;hackage&lt;/a&gt;, to encourage contributions.&lt;/p&gt;&lt;p /&gt; 
    </content:encoded>

    <pubDate>Sat, 13 Jun 2009 12:27:00 +0200</pubDate>
    <guid isPermaLink="false">https://www.joachim-breitner.de/blog/archives/330-guid.html</guid>
    
</item>
<item>
    <title>Third place in AI programming contest</title>
    <link>https://www.joachim-breitner.de/blog/archives/328-Third-place-in-AI-programming-contest.html</link>
            <category>English</category>
            <category>Haskell</category>
    
    <comments>https://www.joachim-breitner.de/blog/archives/328-Third-place-in-AI-programming-contest.html#comments</comments>
    <wfw:comment>https://www.joachim-breitner.de/blog/wfwcomment.php?cid=328</wfw:comment>

    <slash:comments>3</slash:comments>
    <wfw:commentRss>https://www.joachim-breitner.de/blog/rss.php?version=2.0&amp;type=comments&amp;cid=328</wfw:commentRss>
    

    <author>mail@joachim-breitner.de (nomeata)</author>
    <content:encoded>
    
&lt;p&gt;
&lt;a href=&quot;https://www.joachim-breitner.de/blog/archives/324-Bejeweled-AI-in-Haskell.html&quot;&gt;My contribution&lt;/a&gt; to the programming contest held by the German „&lt;a href=&quot;http://www.freiesmagazin.de/&quot;&gt;FreiesMagazin&lt;/a&gt;“ got a &lt;a href=&quot;http://www.freiesmagazin.de/20090605-gewinner-des-programmierwettbewerbs-steht-fest&quot;&gt;third place&lt;/a&gt; out of 13 submissions. This is quite good, considering that I only wrote a small wrapper around the generic &lt;a href=&quot;http://hackage.haskell.org/cgi-bin/hackage-scripts/package/game-tree&quot;&gt;game-tree&lt;/a&gt; Haskell library by Colin Adams, and hardly gave any serious thought into the problem.&lt;/p&gt;&lt;p&gt;All entires are &lt;a href=&quot;ftp://ftp.freiesmagazin.de/2009/2009-04-wettbewerb/&quot;&gt;available for download&lt;/a&gt;. I have annotated the table containing the results with the line count as given by &lt;a href=&quot;http://labs.ohloh.net/ohcount&quot;&gt;ohcount&lt;/a&gt;:&lt;/p&gt;
&lt;div align=&quot;center&quot;&gt;
&lt;table cellpadding=&quot;3&quot; border=&quot;1&quot;&gt;
&lt;tbody&gt;&lt;tr&gt;
&lt;td&gt;    &lt;/td&gt;
&lt;td&gt; &lt;/td&gt;
&lt;td align=&quot;center&quot;&gt; &lt;strong&gt;W&lt;/strong&gt; &lt;/td&gt;
&lt;td align=&quot;center&quot;&gt; &lt;strong&gt;D&lt;/strong&gt; &lt;/td&gt;

&lt;td align=&quot;center&quot;&gt; &lt;strong&gt;L&lt;/strong&gt; &lt;/td&gt;
&lt;td align=&quot;center&quot;&gt; &lt;strong&gt;Points&lt;/strong&gt; &lt;/td&gt;
&lt;td align=&quot;center&quot;&gt; &lt;strong&gt;Language&lt;/strong&gt; &lt;/td&gt;
&lt;td align=&quot;center&quot;&gt; &lt;strong&gt;Code lines&lt;/strong&gt; &lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;right&quot;&gt;1.  &lt;/td&gt;
&lt;td align=&quot;left&quot;&gt; Kroschinsky     &lt;/td&gt;
&lt;td align=&quot;center&quot;&gt; 904 &lt;/td&gt;
&lt;td align=&quot;center&quot;&gt; 242 &lt;/td&gt;
&lt;td align=&quot;center&quot;&gt; 54      &lt;/td&gt;
&lt;td align=&quot;center&quot;&gt; 2954 &lt;/td&gt;
&lt;td align=&quot;center&quot;&gt; Python &lt;/td&gt;
&lt;td align=&quot;center&quot;&gt; 589 &lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;right&quot;&gt;2.  &lt;/td&gt;
&lt;td align=&quot;left&quot;&gt; Schulz          &lt;/td&gt;
&lt;td align=&quot;center&quot;&gt; 858 &lt;/td&gt;

&lt;td align=&quot;center&quot;&gt; 263 &lt;/td&gt;
&lt;td align=&quot;center&quot;&gt; 79      &lt;/td&gt;
&lt;td align=&quot;center&quot;&gt; 2837 &lt;/td&gt;
&lt;td align=&quot;center&quot;&gt; Python &lt;/td&gt;
&lt;td align=&quot;center&quot;&gt; 544 &lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;right&quot;&gt;3.  &lt;/td&gt;
&lt;td align=&quot;left&quot;&gt; Breitner        &lt;/td&gt;
&lt;td align=&quot;center&quot;&gt; 837 &lt;/td&gt;

&lt;td align=&quot;center&quot;&gt; 281 &lt;/td&gt;
&lt;td align=&quot;center&quot;&gt; 82      &lt;/td&gt;
&lt;td align=&quot;center&quot;&gt; 2792 &lt;/td&gt;
&lt;td align=&quot;center&quot;&gt; Haskell &lt;/td&gt;
&lt;td align=&quot;center&quot;&gt; 264 &lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;right&quot;&gt;4.  &lt;/td&gt;
&lt;td align=&quot;left&quot;&gt; Jackermeier     &lt;/td&gt;
&lt;td align=&quot;center&quot;&gt; 754 &lt;/td&gt;

&lt;td align=&quot;center&quot;&gt; 306 &lt;/td&gt;
&lt;td align=&quot;center&quot;&gt; 140     &lt;/td&gt;
&lt;td align=&quot;center&quot;&gt; 2568 &lt;/td&gt;
&lt;td align=&quot;center&quot;&gt; Perl &lt;/td&gt;
&lt;td align=&quot;center&quot;&gt; 183 &lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;right&quot;&gt;5.  &lt;/td&gt;
&lt;td align=&quot;left&quot;&gt; Roth            &lt;/td&gt;
&lt;td align=&quot;center&quot;&gt; 574	&lt;/td&gt;

&lt;td align=&quot;center&quot;&gt; 338 &lt;/td&gt;
&lt;td align=&quot;center&quot;&gt; 288     &lt;/td&gt;
&lt;td align=&quot;center&quot;&gt; 2060 &lt;/td&gt;
&lt;td align=&quot;center&quot;&gt; C++ &lt;/td&gt;
&lt;td align=&quot;center&quot;&gt; 1731 &lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;right&quot;&gt;6.  &lt;/td&gt;
&lt;td align=&quot;left&quot;&gt; Eitel           &lt;/td&gt;
&lt;td align=&quot;center&quot;&gt; 567 &lt;/td&gt;

&lt;td align=&quot;center&quot;&gt; 355 &lt;/td&gt;
&lt;td align=&quot;center&quot;&gt; 278     &lt;/td&gt;
&lt;td align=&quot;center&quot;&gt; 2056 &lt;/td&gt;
&lt;td align=&quot;center&quot;&gt; Ruby &lt;/td&gt;
&lt;td align=&quot;center&quot;&gt; 352 &lt;/td&gt;

&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;right&quot;&gt;7.  &lt;/td&gt;
&lt;td align=&quot;left&quot;&gt; Reichel         &lt;/td&gt;
&lt;td align=&quot;center&quot;&gt; 342 &lt;/td&gt;

&lt;td align=&quot;center&quot;&gt; 328 &lt;/td&gt;
&lt;td align=&quot;center&quot;&gt; 530     &lt;/td&gt;
&lt;td align=&quot;center&quot;&gt; 1354 &lt;/td&gt;
&lt;td align=&quot;center&quot;&gt; Python &lt;/td&gt;
&lt;td align=&quot;center&quot;&gt; 266 &lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;right&quot;&gt;8.  &lt;/td&gt;
&lt;td align=&quot;left&quot;&gt; Zimmermann      &lt;/td&gt;
&lt;td align=&quot;center&quot;&gt; 303 &lt;/td&gt;

&lt;td align=&quot;center&quot;&gt; 400 &lt;/td&gt;
&lt;td align=&quot;center&quot;&gt; 497     &lt;/td&gt;
&lt;td align=&quot;center&quot;&gt; 1309 &lt;/td&gt;
&lt;td align=&quot;center&quot;&gt; Java &lt;/td&gt;
&lt;td align=&quot;center&quot;&gt; 1070 &lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;right&quot;&gt;9.  &lt;/td&gt;
&lt;td align=&quot;left&quot;&gt; Apensiv         &lt;/td&gt;
&lt;td align=&quot;center&quot;&gt; 190 &lt;/td&gt;

&lt;td align=&quot;center&quot;&gt; 353 &lt;/td&gt;
&lt;td align=&quot;center&quot;&gt; 657     &lt;/td&gt;
&lt;td align=&quot;center&quot;&gt; 923 &lt;/td&gt;
&lt;td align=&quot;center&quot;&gt; Perl &lt;/td&gt;
&lt;td align=&quot;center&quot;&gt; 410 &lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;right&quot;&gt;10. &lt;/td&gt;
&lt;td align=&quot;left&quot;&gt; Maraun          &lt;/td&gt;
&lt;td align=&quot;center&quot;&gt; 150 &lt;/td&gt;

&lt;td align=&quot;center&quot;&gt; 300 &lt;/td&gt;
&lt;td align=&quot;center&quot;&gt; 750     &lt;/td&gt;
&lt;td align=&quot;center&quot;&gt; 750 &lt;/td&gt;
&lt;td align=&quot;center&quot;&gt; C++ &lt;/td&gt;
&lt;td align=&quot;center&quot;&gt; 690 &lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;right&quot;&gt;11. &lt;/td&gt;
&lt;td align=&quot;left&quot;&gt; Golemo          &lt;/td&gt;
&lt;td align=&quot;center&quot;&gt; 131 &lt;/td&gt;

&lt;td align=&quot;center&quot;&gt; 319 &lt;/td&gt;
&lt;td align=&quot;center&quot;&gt; 750     &lt;/td&gt;
&lt;td align=&quot;center&quot;&gt; 712 &lt;/td&gt;
&lt;td align=&quot;center&quot;&gt; Python &lt;/td&gt;
&lt;td align=&quot;center&quot;&gt; 104 &lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;right&quot;&gt;12. &lt;/td&gt;
&lt;td align=&quot;left&quot;&gt; Ziegelwanger    &lt;/td&gt;
&lt;td align=&quot;center&quot;&gt; 120 &lt;/td&gt;

&lt;td align=&quot;center&quot;&gt; 337 &lt;/td&gt;
&lt;td align=&quot;center&quot;&gt; 743     &lt;/td&gt;
&lt;td align=&quot;center&quot;&gt; 697 &lt;/td&gt;
&lt;td align=&quot;center&quot;&gt; C++ &lt;/td&gt;
&lt;td align=&quot;center&quot;&gt; 868 &lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;right&quot;&gt;13. &lt;/td&gt;
&lt;td align=&quot;left&quot;&gt; Fuest           &lt;/td&gt;
&lt;td align=&quot;center&quot;&gt; 32  &lt;/td&gt;

&lt;td align=&quot;center&quot;&gt; 254 &lt;/td&gt;
&lt;td align=&quot;center&quot;&gt; 914     &lt;/td&gt;
&lt;td align=&quot;center&quot;&gt; 350 &lt;/td&gt;
&lt;td align=&quot;center&quot;&gt; Python &lt;/td&gt;
&lt;td align=&quot;center&quot;&gt; 645 &lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;&lt;/div&gt;
&lt;p&gt;Note that the line count for my haskell program includes the game-tree library, which I bundled in my submission. Without it, it’s 156 lines of code I had to write, which is second best in the code golf category.&lt;/p&gt;&lt;p&gt;If you look at the &lt;a href=&quot;http://www.freiesmagazin.de/20090605-gewinner-des-programmierwettbewerbs-steht-fest&quot;&gt;timing statistics&lt;/a&gt;, you will see that my program took the longest. When the contest was started, the timelimit was one minute per round – which I of course tried to use as much as possibly, by increasing the search tree depth. Later into the contest, the rules were changed to limit it to one minute for a whole game, and that long-running programs will get points deducted. I did some &lt;a href=&quot;http://darcs.nomeata.de/cgi-bin/darcsweb.cgi?r=hbejeweler;a=commitdiff;h=20090422213648-23c07-50878471ef59da871bb8744bae4d65bfac022faf.gz&quot;&gt;minor&lt;/a&gt; &lt;a href=&quot;http://darcs.nomeata.de/cgi-bin/darcsweb.cgi?r=hbejeweler;a=commitdiff;h=20090422213659-23c07-9d8129cced9a4d5e29dc59ccac1081e206dd89df.gz&quot;&gt;changes&lt;/a&gt; based on a profiling run, but did otherwise not care too much about performance. I would have tried to improve the runtime by using Haskell’s good ability for parallelization. But when I asked on what kind of machine the code will be run, but they would not tell me. They said that this is a hobby programmer’s contest where allowing for parallelization were not fair, so I did not work in that direction.&lt;/p&gt;&lt;p&gt;All in all it was a positive experience, showing of Haskell’s qualities as a language that you can quickly get good results with.&lt;/p&gt; 
    </content:encoded>

    <pubDate>Fri, 05 Jun 2009 20:49:50 +0200</pubDate>
    <guid isPermaLink="false">https://www.joachim-breitner.de/blog/archives/328-guid.html</guid>
    
</item>
<item>
    <title>darcswatch uploaded to hackage</title>
    <link>https://www.joachim-breitner.de/blog/archives/317-darcswatch-uploaded-to-hackage.html</link>
            <category>English</category>
            <category>Haskell</category>
    
    <comments>https://www.joachim-breitner.de/blog/archives/317-darcswatch-uploaded-to-hackage.html#comments</comments>
    <wfw:comment>https://www.joachim-breitner.de/blog/wfwcomment.php?cid=317</wfw:comment>

    <slash:comments>0</slash:comments>
    <wfw:commentRss>https://www.joachim-breitner.de/blog/rss.php?version=2.0&amp;type=comments&amp;cid=317</wfw:commentRss>
    

    <author>mail@joachim-breitner.de (nomeata)</author>
    <content:encoded>
    
&lt;p&gt;I just made my &lt;a href=&quot;http://hackage.haskell.org/cgi-bin/hackage-scripts/package/darcswatch&quot;&gt;first upload to hackage&lt;/a&gt; (not counting uploads I did during my work in Dresden). Don Steward repeatedly told me to package and upload &lt;a href=&quot;https://www.joachim-breitner.de/blog/archives/290-Announcing-DarcsWatch.html&quot;&gt;darcswatch&lt;/a&gt;, so I just did that. Thanks to Gwern Branwen to contribute the first cabal file.&lt;/p&gt;&lt;p&gt;There is little documentation on how to set up darcswatch yourself, so if you actually want to try it out, you most likely will have to get in touch with me. Note that you can just use the installation on &lt;a href=&quot;http://darcswatch.nomeata.de/&quot;&gt;http://darcswatch.nomeata.de/&lt;/a&gt;.&lt;/p&gt;&lt;p&gt;If you, for some reason, feel like hacking on darcswatch, I’d be interested in memory reduction. I currently process 916 mails containing 1867 patches and 47MB, as well as 13 repositories, some of which are rather large, and the numbers are increasing.&lt;/p&gt; 
    </content:encoded>

    <pubDate>Wed, 21 Jan 2009 23:17:32 +0100</pubDate>
    <guid isPermaLink="false">https://www.joachim-breitner.de/blog/archives/317-guid.html</guid>
    
</item>
<item>
    <title>Handling explicit and implicit recusion in Haskell data</title>
    <link>https://www.joachim-breitner.de/blog/archives/316-Handling-explicit-and-implicit-recusion-in-Haskell-data.html</link>
            <category>English</category>
            <category>Haskell</category>
    
    <comments>https://www.joachim-breitner.de/blog/archives/316-Handling-explicit-and-implicit-recusion-in-Haskell-data.html#comments</comments>
    <wfw:comment>https://www.joachim-breitner.de/blog/wfwcomment.php?cid=316</wfw:comment>

    <slash:comments>7</slash:comments>
    <wfw:commentRss>https://www.joachim-breitner.de/blog/rss.php?version=2.0&amp;type=comments&amp;cid=316</wfw:commentRss>
    

    <author>mail@joachim-breitner.de (nomeata)</author>
    <content:encoded>
    
&lt;p&gt;
For a while I have been pondering over a problem that arises when your functionally written program has some state with cross references – for example a list of users, each of which uses a number of computers, and a list of computers, each having an owner.
&lt;/p&gt;

&lt;h3&gt;Implicit referencing&lt;/h3&gt;
&lt;p&gt;
For doing queries on such data, it would be convenient if every reference is just the referenced object itself. Although we would visualize this as a graph, semantically, it is more like an infinite tree. This is possible in Haskell, due to laziness, and if you create the data structure cleverly, it even uses constant memory, no matter how “deep” you enter this infinite tree (&lt;a href=&quot;https://www.joachim-breitner.de/blog/archives/308-Infinite-loops-in-Haskell.html&quot;&gt;a recent post of mine talks about this&lt;/a&gt;). A possible data definition would be:
&lt;/p&gt;
&lt;pre&gt;data User = User {&lt;br /&gt;	userName :: String,&lt;br /&gt;	uses :: [Computer]&lt;br /&gt;	}&lt;br /&gt;data Computer = Computer {&lt;br /&gt;	computerName :: String,&lt;br /&gt;	owner :: User -- references the Users&lt;br /&gt;	}&lt;br /&gt;data State = State [User] [Computer]&lt;br /&gt;&lt;br /&gt;testState = let user = User &amp;quot;Conrad&amp;quot; [computer]&lt;br /&gt;                computer = Computer &amp;quot;Z3&amp;quot; user &lt;br /&gt;            in State [user] [computer]&lt;/pre&gt;

&lt;h3&gt;Explicit referencing&lt;/h3&gt;
&lt;p&gt;
But such a representation is very unsuitable for updates (at least I can’t think if a nice way of updating such a graph without breaking the internal cross-references) and serialization, which is a must for a &lt;a href=&quot;http://happs.org&quot;&gt;HAppS&lt;/a&gt; based application. So what one would probably start with is this data structure:
&lt;/p&gt;

&lt;pre&gt;data User = User {&lt;br /&gt;	userId :: Int,&lt;br /&gt;	userName :: String,&lt;br /&gt;	uses :: [Int] -- references the Computers&lt;br /&gt;	}&lt;br /&gt;data Computer = Computer {&lt;br /&gt;	computerId :: Int,&lt;br /&gt;	computerName :: String,&lt;br /&gt;	owner :: Int -- references the Users&lt;br /&gt;	}&lt;br /&gt;data State = State [User] [Computer]&lt;br /&gt;&lt;br /&gt;testState = State&lt;br /&gt;		[User 0 &amp;quot;Conrad&amp;quot; [1]]&lt;br /&gt;		[Computer 1 &amp;quot;Z3&amp;quot; 0]&lt;/pre&gt;

&lt;p&gt;I think the semantics of this are clear. Note that the referencing is currently not type-safe, but this can be provided by phantom types. Maybe I’ll write more about that later.
&lt;/p&gt;

&lt;p&gt;
Now imaging you want to display the information about the first computer with your web application. You extract the information with 
&lt;tt&gt;let State _ cs = testState in head cs&lt;/tt&gt; and pass that to your templating engine. But what if your template wants to display the name of the owner? It only has access to his &lt;tt&gt;userId&lt;/tt&gt;. You would either need to know what information the template will ever need, extract that from the state beforehand and pass it along, or give the template access to the whole state. In that case, though, there has to be lookup-logic in your output code, which is also not nice. 
&lt;/p&gt;

&lt;p&gt;Woudln’t it be nice if you could, in your application logic, work with the explicit references, which are easy to modify and store, but somehow turn that into the implicit referencing?&lt;/p&gt;

&lt;h3&gt;Duplicated representation&lt;/h3&gt;
&lt;p&gt;One way would be to have two unrelated sets of data structures, &lt;tt&gt;ExplicitState&lt;/tt&gt;, &lt;tt&gt;ExplicitUser&lt;/tt&gt;, &lt;tt&gt;ExplicitComputer&lt;/tt&gt;, which use explicit identifiers to reference each other, and &lt;tt&gt;ImplicitState&lt;/tt&gt;,... which are defined as the first representation of our state. It is then mostly trivial to write a function that converts &lt;tt&gt;ExplicitState&lt;/tt&gt; to &lt;tt&gt;ImplicitState&lt;/tt&gt;.
&lt;/p&gt;

&lt;p&gt;
The big disadvantage of this is that you have to maintain these two different hierarchies. It also means that every function on the state has to be defined twice, which often almost identical code. Clearly, this is not desirable.
&lt;/p&gt;

&lt;h3&gt;Annotated representation&lt;/h3&gt;
&lt;p&gt;
It would be more elegant if the state is stored in one data type that, controlled by a type parameter, comes in the one or the other representation. To do that, we need two types: One that contains a value, and one that contains just a reference:
&lt;/p&gt;
&lt;pre&gt;newtype Id v = Id v deriving (Show, Typeable, Data)&lt;br /&gt;newtype Ref v = Ref Int deriving (Show, Typeable, Data)&lt;/pre&gt;
&lt;p&gt;
Then we need to adjust our data definitions, to make use of these. (I’ll leave out the names, to keep the code smaller)&lt;/p&gt;
&lt;pre&gt;data User ref = User {&lt;br /&gt;	userId :: Int,&lt;br /&gt;	uses :: [ref (Computer ref)]&lt;br /&gt;	}&lt;br /&gt;data Computer ref = Computer {&lt;br /&gt;	computerId :: Int,&lt;br /&gt;	owner :: ref (User ref)&lt;br /&gt;	}&lt;br /&gt;data State ref = State [User ref] [Computer ref]&lt;/pre&gt;
&lt;p&gt;
Here we introduce a type parameter “ref”, which will later be either &lt;tt&gt;Id&lt;/tt&gt; or &lt;tt&gt;Ref&lt;/tt&gt;. Note that now a reference also states the object it is a reference for, which greatly increases type safety. Functions on these data types that don’t work with the references will be polymorphic in the “ref” type parameter, so only need to be written once. A &lt;tt&gt;User Id&lt;/tt&gt; is a complete user with all related data, while &lt;tt&gt;User Ref&lt;/tt&gt; is a user with only references. And a &lt;tt&gt;Ref (User Ref)&lt;/tt&gt; is reference to a user, which contains references...&lt;/p&gt;

&lt;h3&gt;Not so kind kinds&lt;/h3&gt;
&lt;p&gt;
Did you notice the lack of a deriving clause? Our data structures have the relatively peculiar kind (&lt;tt&gt;(* -&amp;gt; *) -&amp;gt; *&lt;/tt&gt;), which makes it hard for the compiler to derive instances for things like &lt;tt&gt;Show&lt;/tt&gt;. But we already know that we will only use &lt;tt&gt;Id&lt;/tt&gt; or &lt;tt&gt;Ref&lt;/tt&gt; for the type variable, so we can use ghc’s &lt;tt&gt;StandaloneDeriving&lt;/tt&gt; language extension and have these instances created:
&lt;/p&gt;
&lt;pre&gt;deriving instance Show (User Id)&lt;br /&gt;deriving instance Show (User Ref)&lt;br /&gt;deriving instance Show (Computer Id)&lt;br /&gt;deriving instance Show (Computer Ref)&lt;br /&gt;deriving instance Show (State Id)&lt;br /&gt;deriving instance Show (State Ref)&lt;/pre&gt;

&lt;h3&gt;Toggling a type parameter&lt;/h3&gt;
&lt;p&gt;
The next step is to write the conversion function. It will have type
&lt;/p&gt;&lt;pre&gt;unrefState :: State Ref -&amp;gt; State Id&lt;/pre&gt;
&lt;p&gt; For that, and for later, we need lookup functions:&lt;/p&gt;
&lt;pre&gt;unrefUserRef :: State Id -&amp;gt; Ref (User Ref) -&amp;gt; Id (User Id)&lt;br /&gt;unrefUserRef (State l _) (Ref i) = Id $ fromJust $&lt;br /&gt;	find (\u@(User i&#039; _) -&amp;gt; i == i&#039;) l &lt;br /&gt;unrefComputerRef :: State Id -&amp;gt; Ref (Computer Ref) -&amp;gt; Id (Computer Id)&lt;br /&gt;unrefComputerRef (State _ l) (Ref i) = Id $ fromJust $&lt;br /&gt;	find (\u@(Computer i&#039; _) -&amp;gt; i == i&#039;) l &lt;/pre&gt;
&lt;p&gt;
These expect a State (with implicit referencing) and a reference, and look up this reference. The function &lt;tt&gt;unrefState&lt;/tt&gt; then looks like this:
&lt;/p&gt;
&lt;pre&gt;unrefState :: State Ref -&amp;gt; State Id&lt;br /&gt;unrefState (State us cs) =&lt;br /&gt;	let unrefState = State (map (unrefUser unrefState) us)&lt;br /&gt;	                       (map (unrefComp unrefState) cs)&lt;br /&gt;	in unrefState&lt;br /&gt;  where unrefUser :: State Id -&amp;gt; User Ref -&amp;gt; User Id&lt;br /&gt;        unrefUser s (User i refs) = User i (map (unrefComputerRef s) refs)&lt;br /&gt;&lt;br /&gt;	unrefComp :: State Id -&amp;gt; Computer Ref -&amp;gt; Computer Id&lt;br /&gt;	unrefComp s (Computer i ref) = Computer i (unrefUserRef s ref)&lt;/pre&gt;
&lt;p&gt;
Note how we “tie the knot” in the &lt;tt&gt;let&lt;/tt&gt; expression. This is the trick that ensures constant memory consumption, because every reference points back to the same place in memory.
&lt;/p&gt;

&lt;h3&gt;Satisfied already?&lt;/h3&gt;
&lt;p&gt;
So what do we have? We have no duplication of data types, we can write general functions, and we can resolve the explicit referencing. We can also easily write functions like &lt;tt&gt;unrefUser :: State Ref -&amp;gt; User Ref -&amp;gt; User Id&lt;/tt&gt;, which transform just a part of the state.&lt;/p&gt;

&lt;p&gt;
But writing &lt;tt&gt;unrefState&lt;/tt&gt; is very tedious when the State becomes more complex. Each of the other &lt;tt&gt;unrefSomething&lt;/tt&gt; functions are very similar, but need to be written anyways. This is unsatisfactory. What we want, is a generic function, something like
&lt;/p&gt;
&lt;pre&gt;gunref :: State Ref -&amp;gt; a Ref -&amp;gt; a Id&lt;/pre&gt;
&lt;p&gt;
which, given a state with explicit references, replaces all explicit references in the first argument (which could be &lt;tt&gt;State Ref&lt;/tt&gt; or &lt;tt&gt;User Ref&lt;/tt&gt; or anything like that) with implicit ones. This function can not exist, because we would not know anything about &lt;tt&gt;a&lt;/tt&gt; and &lt;tt&gt;b&lt;/tt&gt;. But maybe we can do this:
&lt;/p&gt;
&lt;pre&gt;gunref :: (Data (a Id), Data (a Ref)) =&amp;gt;  State Ref -&amp;gt; a Ref -&amp;gt; a Id&lt;/pre&gt;

&lt;h3&gt;Typeable and Data&lt;/h3&gt;
&lt;p&gt;
Before being able to do so, we need to derive &lt;tt&gt;&lt;a href=&quot;http://haskell.org/ghc/docs/latest/html/libraries/base/Data-Data.html#t%3AData&quot;&gt;Data&lt;/a&gt;&lt;/tt&gt; for our types. We can start with
&lt;/p&gt;
&lt;pre&gt;deriving instance Data (User Id)&lt;br /&gt;deriving instance Data (User Ref)&lt;br /&gt;deriving instance Data (Computer Id)&lt;br /&gt;deriving instance Data (Computer Ref)&lt;br /&gt;deriving instance Data (State Id)&lt;br /&gt;deriving instance Data (State Ref&lt;/pre&gt;
&lt;p&gt;
but that will complain about missing &lt;tt&gt;&lt;a href=&quot;http://haskell.org/ghc/docs/latest/html/libraries/base/Data-Typeable.html#t%3ATypeable&quot;&gt;Typeable&lt;/a&gt;&lt;/tt&gt; instances. Unfortunately, ghc’s deriver for &lt;tt&gt;Typeable&lt;/tt&gt; (even the stand-alone-one), does not handle our peculiar kind, so we need to do it by hand. With some help from quicksilver on #haskell, I got it to work:
&lt;/p&gt;
&lt;pre&gt;instance Typeable1 ref =&amp;gt; Typeable (User ref) where&lt;br /&gt;	typeOf _ = mkTyConApp (mkTyCon &amp;quot;User&amp;quot;)     [typeOf1 (undefined :: ref ())]&lt;br /&gt;instance Typeable1 ref =&amp;gt; Typeable (Computer ref) where &lt;br /&gt;	typeOf _ = mkTyConApp (mkTyCon &amp;quot;Computer&amp;quot;) [typeOf1 (undefined :: ref ())]&lt;br /&gt;instance Typeable1 ref =&amp;gt; Typeable (State ref) where &lt;br /&gt;	typeOf _ = mkTyConApp (mkTyCon &amp;quot;State&amp;quot;)    [typeOf1 (undefined :: ref ())]&lt;/pre&gt;

&lt;h3&gt;&lt;tt&gt;everywhere&lt;/tt&gt; is not enough&lt;/h3&gt;
&lt;p&gt;Turning to the documentation of &lt;tt&gt;&lt;a href=&quot;http://haskell.org/ghc/docs/latest/html/libraries/syb/Data-Generics.html&quot;&gt;Data.Generics&lt;/a&gt;&lt;/tt&gt;, I notice with some disappointment that there is no function that is able to &lt;em&gt;change&lt;/em&gt; a type – they all seem to replace a value by another value of the same type. But the functions &lt;tt&gt;&lt;a href=&quot;http://haskell.org/ghc/docs/latest/html/libraries/base/Data-Data.html#v%3Agfoldl&quot;&gt;gfoldl&lt;/a&gt;&lt;/tt&gt; and &lt;tt&gt;&lt;a href=&quot;http://haskell.org/ghc/docs/latest/html/libraries/base/Data-Data.html#v%3Agunfold&quot;&gt;gunfold&lt;/a&gt;&lt;/tt&gt; sounded like they could be used for this.
&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Warning:&lt;/strong&gt; What comes now is a very non-haskellish hack that subverts the type system, just to get the job done. Please read it with a healthy portion of distrust. If you know of a cleaner way of doing that, please tell me!&lt;/p&gt;

&lt;h3&gt;Wrapped Data&lt;/h3&gt;
&lt;p&gt;I want to do some heavy type hackery, so I need to disable haskell’s type system. There is &lt;tt&gt;&lt;a href=&quot;http://haskell.org/ghc/docs/latest/html/libraries/base/Data-Dynamic.html&quot;&gt;Data.Dynamic&lt;/a&gt;&lt;/tt&gt;, but not even that is enough, as we need to carry a type’s &lt;tt&gt;Data&lt;/tt&gt; instance around as well. So let’s wrap that up:
&lt;/p&gt;
&lt;pre&gt;data AData where AData :: Data a =&amp;gt; a -&amp;gt; AData&lt;br /&gt;instance Show AData where show (AData a) = &amp;quot;&amp;lt;&amp;quot; ++ show (typeOf a) ++ &amp;quot;&amp;gt;&amp;quot;&lt;br /&gt;&lt;br /&gt;fromADataE :: forall b. Data b =&amp;gt; AData -&amp;gt; b&lt;br /&gt;fromADataE (AData d) = case cast d of&lt;br /&gt;	Just v -&amp;gt; v&lt;br /&gt;	Nothing -&amp;gt; error $ &amp;quot;Type error, trying to convert &amp;quot; ++&lt;br /&gt;			   show (typeOf d) ++ &amp;quot; to  &amp;quot; ++&lt;br /&gt;			   show (typeOf (undefined :: b)) ++ &amp;quot;.&amp;quot;&lt;/pre&gt;
&lt;p&gt;There is also a function that converts an &lt;tt&gt;AData&lt;/tt&gt; back to a normal type, if possible. If it’s not possible, then there is a bug in our code, so we give an informative error message.
&lt;/p&gt;

&lt;h3&gt;AData transformers&lt;/h3&gt;
&lt;p&gt;
Similar to &lt;tt&gt;&lt;a href=&quot;http://haskell.org/ghc/docs/latest/html/libraries/syb/Data-Generics-Schemes.html#v%3Aeverywhere&quot;&gt;everywhere&lt;/a&gt;&lt;/tt&gt;, we want to have transformers that combinable. They need to have the change to convert an arbitrary value, but also signal that they could not convert something (and this something has to be recursed into). I came up with this:
&lt;/p&gt;
&lt;pre&gt;type ADataT = AData -&amp;gt; Maybe AData&lt;br /&gt;&lt;br /&gt;extADT :: forall a b. (Data a, Data b) =&amp;gt; ADataT -&amp;gt; (a -&amp;gt; b) -&amp;gt; ADataT&lt;br /&gt;extADT at t a@(AData v) = case cast v of &lt;br /&gt;		Just x -&amp;gt;  Just (AData (t x))&lt;br /&gt;		Nothing -&amp;gt; at a&lt;br /&gt;&lt;br /&gt;doNothing :: ADataT&lt;br /&gt;doNothing = const Nothing&lt;/pre&gt;
&lt;p&gt;
&lt;tt&gt;ADataT&lt;/tt&gt; is the type for such a transformer. &lt;tt&gt;doNothing&lt;/tt&gt; will not transform anything, and &lt;tt&gt;extADT&lt;/tt&gt; can be used to add any function to the list of tried transformers, in the spirit of &lt;tt&gt;&lt;a href=&quot;http://haskell.org/ghc/docs/latest/html/libraries/syb/Data-Generics-Aliases.html#v%3AextT&quot;&gt;extT&lt;/a&gt;&lt;/tt&gt;.
&lt;/p&gt;

&lt;h3&gt;The ugly part&lt;/h3&gt;
&lt;p&gt;
To apply such a transformer, I want to use this function, which I’ll describe in the code comments:
&lt;/p&gt;
&lt;pre&gt;everywhereADT :: forall a b. (Data a, Data b) =&amp;gt; ADataT -&amp;gt; a -&amp;gt; b&lt;br /&gt;&lt;br /&gt;-- first check if we can transform this value already&lt;br /&gt;everywhereADT f v = case f (AData v) of&lt;br /&gt;        -- if so, coerce it to the users’ requested type, which hopefully goes well&lt;br /&gt;	Just r -&amp;gt;  fromADataE r &lt;br /&gt;	-- if not, we need to recurse into the data structure&lt;br /&gt;	Nothing -&amp;gt; recursed&lt;br /&gt;&lt;br /&gt;	-- for that, we first need to figure out the arguments to the &lt;br /&gt;        -- constructor. We store them in the untyped list&lt;br /&gt;  where args :: [AData]&lt;br /&gt;        (Const args) = gfoldl k z v&lt;br /&gt;	-- gfoldl lets us have a look at each argument. We wrap it in AData&lt;br /&gt;        -- and append it to the list&lt;br /&gt;	k (Const args) arg = Const (AData arg : args)&lt;br /&gt;	z start = Const []&lt;br /&gt;&lt;br /&gt;	-- We need the data constructor of the input data type. If the user did not want&lt;br /&gt;        -- it to be transformed, it will be the same&lt;br /&gt;	c = toConstr v&lt;br /&gt;&lt;br /&gt;	-- To give better error messages, we make sure that the outmost type constructor&lt;br /&gt;        -- of the requested type actually has the data constructor we were given. Otherwise&lt;br /&gt;        -- gunfold will complain in a non-helpful way&lt;br /&gt;	input_type = dataTypeRep (constrType c)&lt;br /&gt;	output_type = dataTypeRep (dataTypeOf (undefined :: b))&lt;br /&gt;&lt;br /&gt;	recursed = if input_type /= output_type&lt;br /&gt;                   then error $ &amp;quot;Can not convert &amp;lt;&amp;quot; ++ show input_type ++ &amp;quot;&amp;gt;&amp;quot;++&lt;br /&gt;                                            &amp;quot; to &amp;lt;&amp;quot; ++ show output_type ++ &amp;quot;&amp;gt;.&amp;quot;&lt;br /&gt;	-- the types match, so we assemble the output type, using gunfold&lt;br /&gt;                   else snd (gunfold k&#039; z&#039; c)&lt;br /&gt;	k&#039; :: forall b r . Data b =&amp;gt; ([AData], b -&amp;gt; r) -&amp;gt; ([AData],r)&lt;br /&gt;&lt;br /&gt;	-- we start by reversing the input list&lt;br /&gt;	z&#039; start = (reverse args,start)&lt;br /&gt;	&lt;br /&gt;	-- then we call us recursively on the argument and feed the result&lt;br /&gt;        -- to the output constructor&lt;br /&gt;	k&#039; ((AData a) : args, append) = (args, append (everywhereADT f a))&lt;br /&gt;&lt;br /&gt;-- Used for folding (we don’t need to retain the original constructor)&lt;br /&gt;data Const a b = Const a &lt;/pre&gt;
&lt;p&gt;
What a beast! But surprisingly, it works. Here are some examples. Note that I always have to specify the requested output type:
&lt;/p&gt;
&lt;pre&gt;bool2Int :: Bool -&amp;gt; Int&lt;br /&gt;bool2Int False = 0&lt;br /&gt;bool2Int True = 1&lt;br /&gt;&lt;br /&gt;*Main&amp;gt; everywhereADT (doNothing `extADT` bool2Int) True :: Int&lt;br /&gt;1&lt;br /&gt;*Main&amp;gt; everywhereADT (doNothing `extADT` bool2Int) True :: ()&lt;br /&gt;*** Exception: Type error, trying to convert Int to  ().&lt;br /&gt;*Main&amp;gt; everywhereADT (doNothing `extADT` bool2Int) (True,False) :: (Int,Int)&lt;br /&gt;(1,0)&lt;br /&gt;*Main&amp;gt; everywhereADT (doNothing `extADT` bool2Int) ([True,False],True,()) :: ([Int],Int,())&lt;br /&gt;([1,0],1,())&lt;br /&gt;*Main&amp;gt; everywhereADT (doNothing `extADT` bool2Int) ([True,False],True,()) :: [()]&lt;br /&gt;*** Exception: Can not convert &lt;algrep&gt; to &lt;algrep&gt;.&lt;br /&gt;*Main&amp;gt; everywhereADT (doNothing `extADT` bool2Int) [True] :: [Bool]&lt;br /&gt;[*** Exception: Type error, trying to convert Int to  Bool.&lt;/algrep&gt;&lt;/algrep&gt;&lt;/pre&gt;
&lt;p&gt;
I hope this code does not inflict too much pain on any Haskell-loving reader. I know I violated the language, but I didn’t know how to do it better (at least not without using Template Haskell). I also know that this is not very good performance wide: Every single value in the input will be deconstructed, type-compared several times and re-assembled. If that is an issue, then this function should only be used for prototyping.
&lt;/p&gt;

&lt;h3&gt;Almost done&lt;/h3&gt;
&lt;p&gt;
To apply this to our state, we only need to glue it to our lookup functions from above:
&lt;/p&gt;
&lt;pre&gt;gunref :: (Data (a Id), Data (a Ref)) =&amp;gt;  State Ref -&amp;gt; a Ref -&amp;gt; a Id&lt;br /&gt;gunref s w = let unrefState = gunref&#039; unrefState s&lt;br /&gt;             in gunref&#039; unrefState w&lt;br /&gt;&lt;br /&gt;gunref&#039; :: (Data (a Id), Data (a Ref)) =&amp;gt;  State Id -&amp;gt; a Ref -&amp;gt; a Id&lt;br /&gt;gunref&#039; unrefState = everywhereADT unref&#039;&lt;br /&gt;  where unref&#039; = doNothing `extADT`&lt;br /&gt;		 unrefUserRef unrefState `extADT`&lt;br /&gt;		 unrefComputerRef unrefState&lt;/pre&gt;
&lt;p&gt;Now we have a generic unreferencer. I set the type a bit more specific than necessary, to make it safe to use (under the assumption that the list of lookup functions is complete and will not leave any &lt;tt&gt;Ref&lt;/tt&gt; in the output).
&lt;/p&gt;
&lt;pre&gt;*Main&amp;gt; testState &lt;br /&gt;State [User {userId = 0, uses = [Ref 1]}] [Computer {computerId = 1, owner = Ref 0}]&lt;br /&gt;*Main&amp;gt; gunref testState testState &lt;br /&gt;State [User {userId = 0, uses = [Id (Computer {computerId = 1, owner = Id (User {userId = 0,&lt;br /&gt;uses = [Id (Computer {computerId = 1, owner = Id (User {userId = 0, uses = ..&lt;/pre&gt;
&lt;p&gt;
Oh, and by the way, if you want to test this code, you’ll need at least:
&lt;/p&gt;
&lt;pre&gt;{-# LANGUAGE DeriveDataTypeable, FlexibleInstances, GADTs,&lt;br /&gt;             FlexibleContexts, StandaloneDeriving, ScopedTypeVariables #-}&lt;/pre&gt; 
    </content:encoded>

    <pubDate>Wed, 31 Dec 2008 16:21:28 +0100</pubDate>
    <guid isPermaLink="false">https://www.joachim-breitner.de/blog/archives/316-guid.html</guid>
    
</item>
<item>
    <title>MuMer relaunch – preview online</title>
    <link>https://www.joachim-breitner.de/blog/archives/314-MuMer-relaunch-preview-online.html</link>
            <category>English</category>
            <category>Haskell</category>
            <category>Mumer</category>
    
    <comments>https://www.joachim-breitner.de/blog/archives/314-MuMer-relaunch-preview-online.html#comments</comments>
    <wfw:comment>https://www.joachim-breitner.de/blog/wfwcomment.php?cid=314</wfw:comment>

    <slash:comments>9</slash:comments>
    <wfw:commentRss>https://www.joachim-breitner.de/blog/rss.php?version=2.0&amp;type=comments&amp;cid=314</wfw:commentRss>
    

    <author>mail@joachim-breitner.de (nomeata)</author>
    <content:encoded>
    
&lt;p&gt;A &lt;a href=&quot;https://www.joachim-breitner.de/blog/archives/71-Mundus-Mercaturae.html&quot;&gt;few&lt;/a&gt; &lt;a href=&quot;https://www.joachim-breitner.de/blog/archives/104-Mumer-nimmt-langsam-Gestalt-an.html&quot;&gt;years&lt;/a&gt; &lt;a href=&quot;https://www.joachim-breitner.de/blog/archives/261-Internet-Trading-Game-Idea.html&quot;&gt;ago&lt;/a&gt;, I had some ideas about a real-world trading game. In short, a combination of the game play of “&lt;a href=&quot;http://en.wikipedia.org/wiki/Settlers_of_Catan&quot;&gt;Settlers of Catan&lt;/a&gt;”, the cute pseudo-medieval world of “&lt;a href=&quot;http://en.wikipedia.org/wiki/The_Settlers&quot;&gt;The Settlers&lt;/a&gt;” (the computer game), which you can play in your every day live along, without having to sit in front of the computer for a long time. I then started some code, lost motivation and let it sit there for a while.&lt;/p&gt;&lt;p&gt;Recently, I re-developed interest in the idea and started from scratch, using &lt;a href=&quot;http://haskell.org/&quot;&gt;Haskell&lt;/a&gt; and &lt;a href=&quot;http://happs.org/&quot;&gt;HAppS&lt;/a&gt;. To avoid losing interest again, I’m now putting the code online and set up the server. I invite everyone to play around with it, maybe have a look at the code, send me patches or comments. As you can see, the web user interface is plain ugly HTML and could need some love. Some CSS is definitely needed, some AJAX would be nice.  Also, the resource tree is very small at the moment – there are a lot of things to work on, even if you don’t want to touch Haskell!&lt;/p&gt;&lt;p&gt;You can register at &lt;a href=&quot;http://mumer.net/&quot;&gt;http://mumer.net/&lt;/a&gt;. You will be either given a forest (a source for wood) or a source of stone. You can reap your source, and trade on the “Free Market”, which is where you can always trade online, at bad prices. The idea is that you find real trade partners, to get better prices.&lt;/p&gt;&lt;p&gt;For now, trading without physical contact is possible. You can create so-called issue ids, which represent stips of paper. You can then load resources on them, and give the paper (i.e. the number) to other players, who can then redeem them. Eventually, it is planned that these pieces of paper are provided centrally and (sufficiently) unforgeable, so that it is clear who owns a resource.&lt;/p&gt;&lt;p&gt;You can also bid on certain stuff, such as a sawmil, which allows you to turn wood into boards. It will regularily be re-leased to the highest bidder.&lt;/p&gt;&lt;p&gt;You can get the code (in a darcs repository) from &lt;a href=&quot;http://darcs.nomeata.de/mumer2/&quot;&gt;http://darcs.nomeata.de/mumer2&lt;/a&gt; and also &lt;a href=&quot;http://darcs.nomeata.de/cgi-bin/darcsweb.cgi?r=mumer2;a=summary&quot;&gt;browse the code&lt;/a&gt;.&lt;/p&gt;&lt;p&gt;If you happen to be at the &lt;a href=&quot;http://events.ccc.de/congress/2008/&quot;&gt;CCC&lt;/a&gt; right now and would like to talk about it, please do so!&lt;/p&gt; 
    </content:encoded>

    <pubDate>Sun, 28 Dec 2008 13:33:42 +0100</pubDate>
    <guid isPermaLink="false">https://www.joachim-breitner.de/blog/archives/314-guid.html</guid>
    
</item>
<item>
    <title>Infinite loops in Haskell</title>
    <link>https://www.joachim-breitner.de/blog/archives/308-Infinite-loops-in-Haskell.html</link>
            <category>English</category>
            <category>Haskell</category>
    
    <comments>https://www.joachim-breitner.de/blog/archives/308-Infinite-loops-in-Haskell.html#comments</comments>
    <wfw:comment>https://www.joachim-breitner.de/blog/wfwcomment.php?cid=308</wfw:comment>

    <slash:comments>3</slash:comments>
    <wfw:commentRss>https://www.joachim-breitner.de/blog/rss.php?version=2.0&amp;type=comments&amp;cid=308</wfw:commentRss>
    

    <author>mail@joachim-breitner.de (nomeata)</author>
    <content:encoded>
    
&lt;p&gt;Just some small thoughts about cyclic lists in Haskell. Every Haskell beginner knows that you can use infinite lists, as long as you don’t fully evalute them. So, this is perfectly valid&lt;/p&gt;&lt;pre&gt;endless = [0..] -- All natural numbers!
main = print (endless !! 10)&lt;/pre&gt;&lt;p&gt;It will not crash, but print &amp;quot;10&amp;quot; as the list has not been fully used.&lt;/p&gt;&lt;p&gt;What happens if we take a piece of the list further down, let’s say at position 1000000000:&lt;/p&gt;&lt;pre&gt;endles = [0..]
main = print (endless !! (10^9) )&lt;/pre&gt;&lt;p&gt;If you try this at home, better run &amp;quot;&lt;tt&gt;ulimit -S -v 1000000&lt;/tt&gt;&amp;quot; before, because then you’ll get &amp;quot;&lt;tt&gt;test: out of memory (requested 1048576 bytes)&lt;/tt&gt;&amp;quot; instead of a sluggishly swapping machine. What happened? The long list will be evaluated, and fills the memory. &lt;/p&gt;&lt;p&gt;Does this mean that we can not use arbitrary long lists? Let’s try a special case: A list that is infinitely long, but repeating the same values all over again:&lt;/p&gt;&lt;pre&gt;list = &amp;quot;Oh, happy day! Oh, happy day. &amp;quot;&lt;br /&gt;cycle&#039; list = list ++ cycle&#039; list&lt;br /&gt;main = do let rlist = cycle&#039; list&lt;br /&gt;          print ( rlist !! (10^9), rlist !! 0 )&lt;/pre&gt;&lt;p&gt;We repeat the (finite) list endlessly, and then try to pick the 1000000000th element. We also pick the first element again, to make sure the compiler does not cheat by forgetting the first 999999999 elements (It’s actually pretty nice that the compiler will forget these elements, but not what I want to demonstrate here). Running that code, sure enough, fills up the memory.&lt;/p&gt;&lt;p&gt;But maybe I was coding badly. At least I have re-implemented a function that already exists, which is bad practice. Let’s try with Haskell’s own &lt;a href=&quot;http://haskell.org/ghc/docs/latest/html/libraries/base/Data-List.html#v:cycle&quot;&gt;cycle&lt;/a&gt;:&lt;/p&gt;&lt;pre&gt;list = &amp;quot;Oh, happy day! Oh, happy day. &amp;quot;&lt;br /&gt;main = do let rlist = cycle list&lt;br /&gt;          print ( rlist !! (10^9), rlist !! 0 )&lt;/pre&gt;&lt;p&gt;Now it takes a while, but surprisingly, the memory gauge does not skyrocket, and in the end I’m told that the 1000000000th character in my infinite character string is &#039;d&#039;. This leads me to the conclusion that the Haskell library uses black magic. Or does it? Here is the definition of cycle:&lt;/p&gt;&lt;pre&gt;cycle xs = xs&#039; where xs&#039; = xs ++ xs&#039;&lt;/pre&gt;&lt;p&gt;What is the difference to our cycle&#039;? Here, the result is given a name (&lt;tt&gt;xs&#039;&lt;/tt&gt;), which is used again inside the function. So while our cycle&#039; appends the list over and over again, filling up the RAM, their cycle ties a loop and makes the end of the list refer to it’s beginning. And my list lookup will no longer evaluate the list up to infinity, but just run around in, well, cycles until it has counted down from 1000000000. I could even ask for the last element of this list, and it will not use any more RAM than a small, finite list, while endlessly searching for the end of the list.&lt;/p&gt;&lt;p&gt;Despite Haskell being a very high level language, I sometimes wonder how my data will look like on the physical memory. And as you can see, it can make a difference. Some more thoughts on this were written down by &lt;a href=&quot;http://web.comlab.ox.ac.uk/people/Duncan.Coutts/papers/recursive_data_structures_in_haskell.pdf&quot;&gt;Duncan Coutts&lt;/a&gt;.&lt;/p&gt; 
    </content:encoded>

    <pubDate>Wed, 15 Oct 2008 23:04:59 +0200</pubDate>
    <guid isPermaLink="false">https://www.joachim-breitner.de/blog/archives/308-guid.html</guid>
    
</item>
<item>
    <title>Haskell work in Dresden</title>
    <link>https://www.joachim-breitner.de/blog/archives/305-Haskell-work-in-Dresden.html</link>
            <category>English</category>
            <category>Haskell</category>
    
    <comments>https://www.joachim-breitner.de/blog/archives/305-Haskell-work-in-Dresden.html#comments</comments>
    <wfw:comment>https://www.joachim-breitner.de/blog/wfwcomment.php?cid=305</wfw:comment>

    <slash:comments>0</slash:comments>
    <wfw:commentRss>https://www.joachim-breitner.de/blog/rss.php?version=2.0&amp;type=comments&amp;cid=305</wfw:commentRss>
    

    <author>mail@joachim-breitner.de (nomeata)</author>
    <content:encoded>
    
&lt;p&gt;Since Saturday, I’m in Dresden, to work for &lt;a href=&quot;http://wwwtcs.inf.tu-dresden.de/~voigt/&quot;&gt;Janis Voigtländer&lt;/a&gt; at the &lt;a href=&quot;http://tu-dresden.de/&quot;&gt;TU Dresden&lt;/a&gt; on some of his projects. I’m mostly working with his code from “&lt;a href=&quot;http://wwwtcs.inf.tu-dresden.de/~voigt/popl09-2.pdf&quot;&gt;Bidirectionalization for Free&lt;/a&gt;”: &lt;a href=&quot;http://hackage.haskell.org/cgi-bin/hackage-scripts/package/QuickCheck&quot;&gt;QuickCheck&lt;/a&gt;-Properties, statstics, a web interface. I’ll do this for just two weeks, and then return to Karlsruhe.&lt;/p&gt;&lt;p&gt;So if someone wants to meet me, maybe for some Keysigning (since DebConf8, I’m on &lt;a href=&quot;http://pgp.cs.uu.nl/stats/4743206C.html&quot;&gt;Rank 31&lt;/a&gt;, so it’s worth it :-)), just drop me a note.&lt;/p&gt; 
    </content:encoded>

    <pubDate>Wed, 08 Oct 2008 23:14:45 +0200</pubDate>
    <guid isPermaLink="false">https://www.joachim-breitner.de/blog/archives/305-guid.html</guid>
    
</item>
<item>
    <title>FrakView: An Haskell Renderer for Iterated Function Systems</title>
    <link>https://www.joachim-breitner.de/blog/archives/292-FrakView-An-Haskell-Renderer-for-Iterated-Function-Systems.html</link>
            <category>English</category>
            <category>Haskell</category>
    
    <comments>https://www.joachim-breitner.de/blog/archives/292-FrakView-An-Haskell-Renderer-for-Iterated-Function-Systems.html#comments</comments>
    <wfw:comment>https://www.joachim-breitner.de/blog/wfwcomment.php?cid=292</wfw:comment>

    <slash:comments>0</slash:comments>
    <wfw:commentRss>https://www.joachim-breitner.de/blog/rss.php?version=2.0&amp;type=comments&amp;cid=292</wfw:commentRss>
    

    <author>mail@joachim-breitner.de (nomeata)</author>
    <content:encoded>
    
&lt;p&gt;For a recent university seminar, I wrote a haskell program to render and edit &lt;a href=&quot;http://en.wikipedia.org/wiki/Iterated_function_system&quot;&gt;iterated function systems&lt;/a&gt; (IFS), which generates a certain class of fractals, namely self-similar sets. I think the result is quite nice, so I’m sharing the code.&lt;/p&gt;
&lt;div align=&quot;center&quot;&gt;&lt;a href=&quot;http://darcs.nomeata.de/FrakView/screenshot-2008-05-17.png&quot;&gt;&lt;img width=&quot;394&quot; border=&quot;0&quot; src=&quot;http://darcs.nomeata.de/FrakView/screenshot-2008-05-17.png&quot; alt=&quot;FrakView screenshot&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;p&gt;With FrakView you can view a rendering of the attractor of the IFS, with a choice of two algorithms (a straight forward, and a probabilistic), configurable depth and anti-aliasing. You can also modify the IFS by dragging the colored boxes with arrows you see on the screenshot. For the academically inclined, there is also support to visualize cylinder sets and otherwise explore the coding space of the IFS a bit.&lt;/p&gt;&lt;p&gt;The program is written in &lt;a href=&quot;http://haskell.org/&quot;&gt;haskell&lt;/a&gt; and uses &lt;a href=&quot;http://haskell.org/gtk2hs/&quot;&gt;gtk2hs&lt;/a&gt;, the &lt;a href=&quot;http://www.gtk.org/&quot;&gt;gtk&lt;/a&gt; bindings for haskell. It might be interesting for other gtk2hs programmers to see how FrakView solves some issues: For example, it uses the &lt;a href=&quot;https://www.joachim-breitner.de/blog/archives/291-Pausable-IO-actions-for-better-GUI-responsiveness.html&quot;&gt;&lt;tt&gt;CoroutineT&lt;/tt&gt; monad transformer&lt;/a&gt; I recently blogged about – check out the &lt;tt&gt;pausingForM_&lt;/tt&gt; function in &lt;a href=&quot;http://darcs.nomeata.de/FrakView/GUI.hs&quot;&gt;&lt;tt&gt;GUI.hs&lt;/tt&gt;&lt;/a&gt;. Also, the current state of the screen is in one algebraic data type (&lt;tt&gt;ScreenConfig&lt;/tt&gt;) that supports equality checks, so when the user interacts, the code recomputes the new &lt;tt&gt;ScreenConfig&lt;/tt&gt; (using &lt;tt&gt;getRenderer&lt;/tt&gt;), but only redraws the screen if it differs from the previous. This is much easier and more robust than having to decide for each possible user interaction whether it changes what’s on the screen.&lt;/p&gt;&lt;p&gt;You can get the source from the &lt;a href=&quot;http://darcs.nomeata.de/FrakView/&quot;&gt;FrakView darcs&lt;/a&gt; repository.&lt;/p&gt; 
    </content:encoded>

    <pubDate>Sat, 17 May 2008 14:31:10 +0200</pubDate>
    <guid isPermaLink="false">https://www.joachim-breitner.de/blog/archives/292-guid.html</guid>
    
</item>

</channel>
</rss>