<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:georss='http://www.georss.org/georss' xmlns:gd='http://schemas.google.com/g/2005' xmlns:thr='http://purl.org/syndication/thread/1.0'><id>tag:blogger.com,1999:blog-37404288</id><updated>2012-01-22T20:32:29.882+01:00</updated><category term='Python'/><category term='Neural Network'/><category term='Scion'/><category term='development'/><category term='Parsec'/><category term='Hibernate'/><category term='Software design'/><category term='annotations'/><category term='Dynamic languages'/><category term='parsing'/><category term='functions'/><category term='Windows'/><category term='IDE'/><category term='RIA'/><category term='HughesPJ'/><category term='GUI'/><category term='Artificial Intelligence'/><category term='Scala'/><category term='Design By Contract'/><category term='Rhino'/><category term='Hoogle'/><category term='Genetic Programming'/><category term='Flex'/><category term='performance'/><category term='GHC'/><category term='JSON'/><category term='closures'/><category term='buildwrapper'/><category term='scripting'/><category term='Aspects'/><category term='mazes'/><category term='self-indulgence'/><category term='robotics'/><category term='maths'/><category term='Monads'/><category term='games'/><category term='game'/><category term='Java'/><category term='EclipseFP'/><category term='Compilation'/><category term='properties'/><category term='JavaFX'/><category term='Haskell'/><category term='Cabal'/><category term='HGL'/><category term='Functional Programming'/><category term='self-publicity'/><category term='generics'/><category term='Linux'/><category term='Eclipse'/><category term='testing'/><category term='Object Oriented Programming'/><category term='JavaScript'/><category term='Concurrent Programming'/><category term='SWT'/><title type='text'>JP Moresmau's Programming Blog</title><subtitle type='html'>In this blog I talk about some of the personal work I do  in programming. I mainly do Java and JavaScript, but I'm learning functional programming in Haskell too...</subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://jpmoresmau.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/37404288/posts/default?max-results=100'/><link rel='alternate' type='text/html' href='http://jpmoresmau.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><author><name>JP Moresmau</name><uri>http://www.blogger.com/profile/09964251063221757176</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='26' height='32' src='http://4.bp.blogspot.com/_SFBL69b3jRQ/TIUvCsYa5EI/AAAAAAAAACw/4H33zrk1nAI/S220/shades.jpg'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>80</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>100</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-37404288.post-3858137737581856114</id><published>2012-01-16T23:06:00.000+01:00</published><updated>2012-01-16T23:06:18.684+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='robotics'/><category scheme='http://www.blogger.com/atom/ns#' term='Haskell'/><title type='text'>Lego Mindstorms, Haskell, Windows: all set!</title><content type='html'>A new version of the &lt;a href="http://hackage.haskell.org/package/NXT"&gt;NXT &lt;/a&gt;library has been released, and it supports Windows!! I lamented a few weeks ago that it only ran on Unix/MacOs (requiring the unix package and using Posix file descriptors), but that's a thing of the past. It was really easy to port &lt;a href="http://mitar.tnode.com/"&gt;Mitar's&lt;/a&gt; code to use the serialport package instead of file descriptors. Now Mitar has merged back my changes, we've tested the code on Linux and Windows, and it's been released on Hackage!&lt;br /&gt;&lt;br /&gt;So now I can control my Lego Mindstorm robot from Haskell on my Windows machine! World domination is only a couple more steps away!&lt;br /&gt;&lt;br /&gt;I wish to point out that &lt;a href="https://bitbucket.org/mitar/nxt"&gt;Mitar's code&lt;/a&gt; is extremely well commented and a pleasure to work with, which of course made the adaptation to Windows a lot easier. Thank you!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/37404288-3858137737581856114?l=jpmoresmau.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jpmoresmau.blogspot.com/feeds/3858137737581856114/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=37404288&amp;postID=3858137737581856114' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/37404288/posts/default/3858137737581856114'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/37404288/posts/default/3858137737581856114'/><link rel='alternate' type='text/html' href='http://jpmoresmau.blogspot.com/2012/01/lego-mindstorms-haskell-windows-all-set.html' title='Lego Mindstorms, Haskell, Windows: all set!'/><author><name>JP Moresmau</name><uri>http://www.blogger.com/profile/09964251063221757176</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='26' height='32' src='http://4.bp.blogspot.com/_SFBL69b3jRQ/TIUvCsYa5EI/AAAAAAAAACw/4H33zrk1nAI/S220/shades.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-37404288.post-5684194522510963529</id><published>2012-01-13T14:55:00.000+01:00</published><updated>2012-01-13T14:55:44.167+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='IDE'/><category scheme='http://www.blogger.com/atom/ns#' term='self-publicity'/><category scheme='http://www.blogger.com/atom/ns#' term='Haskell'/><category scheme='http://www.blogger.com/atom/ns#' term='EclipseFP'/><title type='text'>EclipseFP 2.2.1 released</title><content type='html'>It is my pleasure to announce a new version of &lt;a href="http://eclipsefp.github.com/"&gt;EclipseFP&lt;/a&gt;. Release 2.2.1 does not bring huge changes in the UI, but comes with important bug fixes and small enhancements. More importantly, it integrates with the latest versions of &lt;a href="http://hackage.haskell.org/package/buildwrapper"&gt;buildwrapper &lt;/a&gt;and &lt;a href="http://hackage.haskell.org/package/scion-browser"&gt;scion-browser&lt;/a&gt;. You can see the release notes &lt;a href="https://sourceforge.net/projects/eclipsefp/files/EclipseFP%202%20branch/2.2.1/"&gt;here&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;We tried to enhance the performance and stability of EclipseFP, while making it easier to work with. The "open definition" action for example should be able to resolve a lot more symbols than before, including in type annotations. Quick fixes and auto-completion we've also worked on.&lt;br /&gt;&lt;br /&gt;I wish to thank all users of EclipseFP, most notably all the people that submit bug reports or questions to the &lt;a href="http://sourceforge.net/projects/eclipsefp/forums/forum/371922"&gt;forum &lt;/a&gt;and thus help make the product move forward!&lt;br /&gt;&lt;br /&gt;The instructions to install are the same as always: point your Eclipse to the update site&amp;nbsp;&lt;a href="http://eclipsefp.sourceforge.net/updates/"&gt;http://eclipsefp.sourceforge.net/updates/&lt;/a&gt;. Once you restart EclipseFP should install or update buildwrapper and scion-browser.&lt;br /&gt;&lt;br /&gt;Happy Haskell Hacking!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/37404288-5684194522510963529?l=jpmoresmau.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jpmoresmau.blogspot.com/feeds/5684194522510963529/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=37404288&amp;postID=5684194522510963529' title='7 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/37404288/posts/default/5684194522510963529'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/37404288/posts/default/5684194522510963529'/><link rel='alternate' type='text/html' href='http://jpmoresmau.blogspot.com/2012/01/eclipsefp-221-released.html' title='EclipseFP 2.2.1 released'/><author><name>JP Moresmau</name><uri>http://www.blogger.com/profile/09964251063221757176</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='26' height='32' src='http://4.bp.blogspot.com/_SFBL69b3jRQ/TIUvCsYa5EI/AAAAAAAAACw/4H33zrk1nAI/S220/shades.jpg'/></author><thr:total>7</thr:total></entry><entry><id>tag:blogger.com,1999:blog-37404288.post-4610028104360271087</id><published>2011-12-30T17:30:00.000+01:00</published><updated>2011-12-30T17:30:19.469+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='IDE'/><category scheme='http://www.blogger.com/atom/ns#' term='Haskell'/><category scheme='http://www.blogger.com/atom/ns#' term='EclipseFP'/><title type='text'>EclipseFP and "the future of programming"</title><content type='html'>Paul Chiusano's essay "&lt;a href="http://pchiusano.blogspot.com/2011/12/future-of-programming.html"&gt;The Future Of Programming&lt;/a&gt;" has sparkled a lot of debate, for example on &lt;a href="http://www.reddit.com/r/programming/comments/nuvh2/the_future_of_programming/"&gt;Reddit&lt;/a&gt;. His points on IDEs remind me somewhat on what &lt;a href="http://lukepalmer.wordpress.com/2010/10/18/idewtf/"&gt;Luke Palmer&lt;/a&gt; has to say on them. And he's strongly in favor of lazy, statically-typed, functional languages.&lt;br /&gt;&lt;br /&gt;I suddenly find myself in a strange (good?) position: as a maintainer of an IDE (ok, plugins) for Haskell, I can somehow participate towards fulfilling that dream. I know, I know, we're far from it, and EclipseFP has not yet reached the ease of use and power of the &lt;a href="http://eclipse.org/jdt/"&gt;JDT&lt;/a&gt; in Eclipse. But maybe we can achieve success by doing things differently, not by trying to mimic what's already there and anyway applies to a different language.&lt;br /&gt;&lt;br /&gt;We've already started to take some steps in the right direction: for example, Alejandro is working on a &lt;a href="https://github.com/serras/scion-class-browser/tree/persistent"&gt;version of scion-browser &lt;/a&gt;that stores its data in a database. It's not such a big leap to envision that a lot of information about the developer's projects and modules could be kept in that database, to give accurate and fast searching and refactoring operations. We'll also need to think about providing an editor that is a lot more structured than the standard text-with-foldable-sections editor we have now, but it's not clear now if&lt;br /&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;the benefits of a structured editor justify developing an interface programmers are not used to&lt;/li&gt;&lt;li&gt;people would take the plunge even if we could prove tangible benefits&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;I can already see a clear advantage in having an editor that always force you to have valid code: EclipseFP loses a lot of functionality (thingAtPoint for example doesn't work) if the module you're working on has errors, because the GHC API can provide a lot more info once the module can be analysed correctly. With things like "undefined" and type-directed autocomplete support we could have modules that are always correct. I'm not sure myself that having a compiling module with loads of undefined that fails miserably at run-time is such a great proposition, but hey... In Java, Eclipse let you run a file with errors and only throws a run-time error when you access the incorrect code. &lt;br /&gt;&lt;br /&gt;So we'll have to overcome usability and performance issues, deal with GHC limitations and programmers' expectations, but we're in the position to at least try, and see if we can move forward a little bit!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/37404288-4610028104360271087?l=jpmoresmau.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jpmoresmau.blogspot.com/feeds/4610028104360271087/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=37404288&amp;postID=4610028104360271087' title='6 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/37404288/posts/default/4610028104360271087'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/37404288/posts/default/4610028104360271087'/><link rel='alternate' type='text/html' href='http://jpmoresmau.blogspot.com/2011/12/eclipsefp-and-future-of-programming.html' title='EclipseFP and &quot;the future of programming&quot;'/><author><name>JP Moresmau</name><uri>http://www.blogger.com/profile/09964251063221757176</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='26' height='32' src='http://4.bp.blogspot.com/_SFBL69b3jRQ/TIUvCsYa5EI/AAAAAAAAACw/4H33zrk1nAI/S220/shades.jpg'/></author><thr:total>6</thr:total></entry><entry><id>tag:blogger.com,1999:blog-37404288.post-4378841618269965882</id><published>2011-12-28T21:41:00.000+01:00</published><updated>2011-12-28T21:41:07.311+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='robotics'/><category scheme='http://www.blogger.com/atom/ns#' term='Haskell'/><title type='text'>Lego Mindstorms and Haskell?</title><content type='html'>Santa brought me a &lt;a href="http://mindstorms.lego.com/"&gt;Lego Mindstorms kit!&lt;/a&gt; Suddenly the time I'm going to have available for EclipseFP is greatly reduced (I joke). I'm having fun building my first little models and fiddling with the graphical interface for programming the little beasts, but I was wondering if I could use &lt;a href="http://www.haskell.org/haskellwiki/RoboticOverlords"&gt;Haskell to control the robots&lt;/a&gt;. Things look bleak:&lt;br /&gt;- the &lt;a href="http://hackage.haskell.org/package/NXT"&gt;NXT &lt;/a&gt;library on Hackage looks good, but requires unix... Maybe getting it to work on Windows would be easy, but I wonder...&lt;br /&gt;- the &lt;a href="http://mindstorms.lego.com/en-us/support/files/default.aspx"&gt;fantom development kit&lt;/a&gt; (fantom is the low level communication API for Mindstorms, if I understand correctly) comes with a Windows version that will only work with Visual C++. It uses C++ lib and dll files whose name mangling is not compatible with MinGW.&lt;br /&gt;&lt;br /&gt;So as a Windows and MinGW user, I'm in a bit of a ditch. I'm wondering now about the &lt;a href="http://www.urbiforge.org/"&gt;Urbi &lt;/a&gt;platform, that seems to be open source and to have a module for Mindstorms. It seems to provide a C++, Java and scripting interfaces, so it may be possible to get a Haskell wrapper on top of it. I wonder has anybody worked on Haskell bindings for Urbi? Might be interesting...&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/37404288-4378841618269965882?l=jpmoresmau.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jpmoresmau.blogspot.com/feeds/4378841618269965882/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=37404288&amp;postID=4378841618269965882' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/37404288/posts/default/4378841618269965882'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/37404288/posts/default/4378841618269965882'/><link rel='alternate' type='text/html' href='http://jpmoresmau.blogspot.com/2011/12/lego-mindstorms-and-haskell.html' title='Lego Mindstorms and Haskell?'/><author><name>JP Moresmau</name><uri>http://www.blogger.com/profile/09964251063221757176</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='26' height='32' src='http://4.bp.blogspot.com/_SFBL69b3jRQ/TIUvCsYa5EI/AAAAAAAAACw/4H33zrk1nAI/S220/shades.jpg'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-37404288.post-6396893074855880001</id><published>2011-12-26T17:29:00.001+01:00</published><updated>2011-12-26T17:30:24.427+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='self-publicity'/><category scheme='http://www.blogger.com/atom/ns#' term='buildwrapper'/><category scheme='http://www.blogger.com/atom/ns#' term='Haskell'/><category scheme='http://www.blogger.com/atom/ns#' term='EclipseFP'/><title type='text'>Buildwrapper 0.2.2 released</title><content type='html'>Hello all, I've just released a new version of &lt;a href="http://hackage.haskell.org/package/buildwrapper"&gt;buildwrapper&lt;/a&gt;, which is one of the backend Haskell executables used in EclipseFP. This is a bug fixing release, addressing some of the issues reported by people. Just install the new version via cabal install or via the EclipseFP cabal packages views.&lt;br /&gt;There is ongoing work on EclipseFP and scion-browser, so a new version of both should hit the shelves pretty soon, in a matter of weeks!&lt;br /&gt;&lt;br /&gt;Happy Haskell Hacking!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/37404288-6396893074855880001?l=jpmoresmau.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jpmoresmau.blogspot.com/feeds/6396893074855880001/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=37404288&amp;postID=6396893074855880001' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/37404288/posts/default/6396893074855880001'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/37404288/posts/default/6396893074855880001'/><link rel='alternate' type='text/html' href='http://jpmoresmau.blogspot.com/2011/12/buildwrapper-022-released.html' title='Buildwrapper 0.2.2 released'/><author><name>JP Moresmau</name><uri>http://www.blogger.com/profile/09964251063221757176</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='26' height='32' src='http://4.bp.blogspot.com/_SFBL69b3jRQ/TIUvCsYa5EI/AAAAAAAAACw/4H33zrk1nAI/S220/shades.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-37404288.post-5276154837259769056</id><published>2011-11-12T23:03:00.001+01:00</published><updated>2011-11-12T23:08:15.085+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Windows'/><category scheme='http://www.blogger.com/atom/ns#' term='EclipseFP'/><title type='text'>EclipseFP helper executables for Windows</title><content type='html'>Since people had sometimes problems building Haskell executables we use in EclipseFP, I thought I'd help by putting versions of the current Windows executables on sourceforge. So in you run Windows and have trouble building scion-browser or buildwrapper, you can grab them from &lt;a href="https://sourceforge.net/projects/eclipsefp/files/EclipseFP%202%20branch/2.2.0/"&gt;here&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;I know this isn't really in the spirit of "build from sources so you can check them yaddi yadda", but since even Cabal does it...&lt;br /&gt;&lt;br /&gt;As usual, use at your own risk, etc.&lt;br /&gt;&lt;br /&gt;Happy Haskell Hacking!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/37404288-5276154837259769056?l=jpmoresmau.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jpmoresmau.blogspot.com/feeds/5276154837259769056/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=37404288&amp;postID=5276154837259769056' title='4 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/37404288/posts/default/5276154837259769056'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/37404288/posts/default/5276154837259769056'/><link rel='alternate' type='text/html' href='http://jpmoresmau.blogspot.com/2011/11/eclipsefp-helper-executables-for.html' title='EclipseFP helper executables for Windows'/><author><name>JP Moresmau</name><uri>http://www.blogger.com/profile/09964251063221757176</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='26' height='32' src='http://4.bp.blogspot.com/_SFBL69b3jRQ/TIUvCsYa5EI/AAAAAAAAACw/4H33zrk1nAI/S220/shades.jpg'/></author><thr:total>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-37404288.post-6434949464965017762</id><published>2011-11-11T17:59:00.001+01:00</published><updated>2011-11-11T18:04:41.395+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='IDE'/><category scheme='http://www.blogger.com/atom/ns#' term='self-publicity'/><category scheme='http://www.blogger.com/atom/ns#' term='Haskell'/><category scheme='http://www.blogger.com/atom/ns#' term='EclipseFP'/><title type='text'>EclipseFP 2.2.0 released!</title><content type='html'>I'm glad to announce that EclipseFP 2.2.0 has been released. &lt;a href="http://eclipsefp.github.com/"&gt;EclipseFP &lt;/a&gt;is a set of Eclipse plugins for Haskell development.&lt;br /&gt;&lt;br /&gt;The minor version increase is justified by the replacement of the Scion library for the backend by the &lt;a href="http://hackage.haskell.org/package/buildwrapper"&gt;BuildWrapper &lt;/a&gt;executable. I appreciate that lots of work went and is still going into Scion, but I decided that building my own Haskell backend was better for EclipseFP. It calls cabal directly for building, which allows EclipseFP to support things like new style component dependencies (the executable in a project depends on its own library), c files (now my HJVM project, which call Java from Haskell can build, and even report errors in the C code), etc. Note the the haskell code is not bundled with EclipseFP anymore but gets downloaded and installed from Hackage.&lt;br /&gt;&lt;br /&gt;This version also comes with a new view, allowing the installation of cabal packages from Hackage. There are also bug fixes and small enhancements all round.&lt;br /&gt;&lt;br /&gt;To install, just use the built-in Eclipse install/update functionality. The update site URL is &lt;a href="http://eclipsefp.sourceforge.net/updates"&gt;http://eclipsefp.sourceforge.net/updates&lt;/a&gt;. The release notes can be found &lt;a href="https://sourceforge.net/projects/eclipsefp/files/EclipseFP%202%20branch/2.2.0/"&gt;here&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;Happy Haskell Hacking with EclipseFP!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/37404288-6434949464965017762?l=jpmoresmau.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jpmoresmau.blogspot.com/feeds/6434949464965017762/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=37404288&amp;postID=6434949464965017762' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/37404288/posts/default/6434949464965017762'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/37404288/posts/default/6434949464965017762'/><link rel='alternate' type='text/html' href='http://jpmoresmau.blogspot.com/2011/11/eclipsefp-220-released.html' title='EclipseFP 2.2.0 released!'/><author><name>JP Moresmau</name><uri>http://www.blogger.com/profile/09964251063221757176</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='26' height='32' src='http://4.bp.blogspot.com/_SFBL69b3jRQ/TIUvCsYa5EI/AAAAAAAAACw/4H33zrk1nAI/S220/shades.jpg'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-37404288.post-2590816228350814942</id><published>2011-10-20T19:44:00.000+02:00</published><updated>2011-10-20T19:44:35.742+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Java'/><category scheme='http://www.blogger.com/atom/ns#' term='testing'/><category scheme='http://www.blogger.com/atom/ns#' term='GUI'/><title type='text'>GUI Testing using OCR: project Sikuli</title><content type='html'>I had a great idea this morning... and then realized that there was an open source project already doing it.&lt;br /&gt;I thought: instead of using specific testing frameworks for each UI technology I have (a tool for the web, a tool for SWT UIs, etc) what about a tool that could recognize the text on screen and click or type in the proper places. The same technology for everything type of UI, and something that doesn't rely on pixel perfect positioning to work! Turns out (surprise!) I'm not the first one that had the idea, and looking around I stumbled on &lt;a href="http://sikuli.org/"&gt;Project Sikuli&lt;/a&gt;. This looks great: it uses images to find "interesting" parts of your UI and there's also support for text recognition. So potentially you could say "click on the button that says 'Submit'"! It integrates with Java code so you can easily have JUnit tests using it.&lt;br /&gt;Unfortunately, for my own purposes I couldn't get very far easily because of&lt;a href="https://bugs.launchpad.net/sikuli/+bug/673995"&gt; lack of support for transparent images&lt;/a&gt; (or, more precisely, it takes into account transparent areas for images, so it doesn't recognize an image if the background changes, which happens if your desktop theme changes, if you use the same icon in different contexts in your UI, etc). But it still looks like a promising tool!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/37404288-2590816228350814942?l=jpmoresmau.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jpmoresmau.blogspot.com/feeds/2590816228350814942/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=37404288&amp;postID=2590816228350814942' title='5 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/37404288/posts/default/2590816228350814942'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/37404288/posts/default/2590816228350814942'/><link rel='alternate' type='text/html' href='http://jpmoresmau.blogspot.com/2011/10/gui-testing-using-ocr-project-sikuli.html' title='GUI Testing using OCR: project Sikuli'/><author><name>JP Moresmau</name><uri>http://www.blogger.com/profile/09964251063221757176</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='26' height='32' src='http://4.bp.blogspot.com/_SFBL69b3jRQ/TIUvCsYa5EI/AAAAAAAAACw/4H33zrk1nAI/S220/shades.jpg'/></author><thr:total>5</thr:total></entry><entry><id>tag:blogger.com,1999:blog-37404288.post-1109223438482587398</id><published>2011-10-13T19:51:00.000+02:00</published><updated>2011-10-13T19:51:10.203+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Cabal'/><category scheme='http://www.blogger.com/atom/ns#' term='Haskell'/><category scheme='http://www.blogger.com/atom/ns#' term='EclipseFP'/><title type='text'>Manage Cabal packages from inside EclipseFP</title><content type='html'>I'm thinking the new version of EclipseFP will not bundle the Haskell code we use, but will download it from Hackage, which would make sense: we would be able to update the Haskell side without requiring a EclipseFP upgrade, and vice versa. I would expect Haskell developers would be quite used to install packages from Hackage using &lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;cabal install&lt;/span&gt;. However, let's try to minimize the number of things that a user would need to go outside of EclipseFP to do on a normal Haskell project. So I've added another view:&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://4.bp.blogspot.com/-ZHY2cx3TNiE/Tpcj-UFv_zI/AAAAAAAAAEs/IIrTMFVSzd0/s1600/cabal_packages_screenshot1.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="324" src="http://4.bp.blogspot.com/-ZHY2cx3TNiE/Tpcj-UFv_zI/AAAAAAAAAEs/IIrTMFVSzd0/s640/cabal_packages_screenshot1.jpg" width="640" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;This view lets you see the list of packages you've installed, with their version, or the full list from Hackage, that you can filter by typing the prefix of the name you're looking for. From there you can install the packages as either Global or User, see the package information, or click on the "More Information" link to open the Hackage page directly.&lt;br /&gt;You can also update the list. This GUI is only a wrapper above the &lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;cabal list&lt;/span&gt; and &lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;cabal info&lt;/span&gt; commands.&lt;br /&gt;Hopefully this will be useful to people! Should I add a text field somewhere to be able to specify more options to &lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;cabal install&lt;/span&gt;, or is that overkill for a GUI?&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/37404288-1109223438482587398?l=jpmoresmau.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jpmoresmau.blogspot.com/feeds/1109223438482587398/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=37404288&amp;postID=1109223438482587398' title='4 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/37404288/posts/default/1109223438482587398'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/37404288/posts/default/1109223438482587398'/><link rel='alternate' type='text/html' href='http://jpmoresmau.blogspot.com/2011/10/manage-cabal-packages-from-inside.html' title='Manage Cabal packages from inside EclipseFP'/><author><name>JP Moresmau</name><uri>http://www.blogger.com/profile/09964251063221757176</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='26' height='32' src='http://4.bp.blogspot.com/_SFBL69b3jRQ/TIUvCsYa5EI/AAAAAAAAACw/4H33zrk1nAI/S220/shades.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://4.bp.blogspot.com/-ZHY2cx3TNiE/Tpcj-UFv_zI/AAAAAAAAAEs/IIrTMFVSzd0/s72-c/cabal_packages_screenshot1.jpg' height='72' width='72'/><thr:total>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-37404288.post-4732310666146341939</id><published>2011-10-07T14:40:00.001+02:00</published><updated>2011-10-07T14:41:36.578+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Cabal'/><category scheme='http://www.blogger.com/atom/ns#' term='Scion'/><category scheme='http://www.blogger.com/atom/ns#' term='GHC'/><category scheme='http://www.blogger.com/atom/ns#' term='EclipseFP'/><title type='text'>New backend for EclipseFP</title><content type='html'>A while ago I was wondering how I could enhance EclipseFP, regarding things like memory usage, support for multi components projects, etc. I now have a working version for adventurous testers!&lt;br /&gt;&lt;br /&gt;The main thing is the removal of Scion. EclipseFP now uses another backend component called "buildwrapper". There is no server, buildwrapper is only an executable that can be launched with flags, and writes a JSON result on the standard output. This means no more huge memory usage, and less synchronization headaches.&lt;br /&gt;&lt;br /&gt;Buildwrapper uses a copy of the project inside a hidden folder. This means that when we want to get say build errors on a dirty editor content, we can write the dirty content to the file inside the hidden folder, and launch a build process on these files, thus avoiding the limitations that the GHC API has on building from a StringBuffer (doesn't work for files requiring preprocessing, etc).&lt;br /&gt;&lt;br /&gt;We only use the &lt;a href="http://www.haskell.org/haskellwiki/GHC/As_a_library"&gt;GHC API&lt;/a&gt; to get the types of things in a source file, but we use Cabal to build the project. Buildwrapper actually launches the cabal executable and parses the results. I know, sounds crude compare to an API only approach, but I have the feeling it just works better. Basically the IDE will now behave a lot close to what you get if you were building your project from the command line. And then you get additional goodies, like multi component support (so you can have the executable of your project reference the library in the same project, and it works!).&lt;br /&gt;&lt;br /&gt;Buildwrapper uses &lt;a href="http://hackage.haskell.org/package/haskell-src-exts"&gt;haskell-src-exts&lt;/a&gt; for outline. I've actually seen cases where it needed language pragmas to parse correctly that GHC didn't need, but such is life.&lt;br /&gt;&lt;br /&gt;Performance seems to be quite good, except for things that use the GHC API, where there's a little lag. Hopefully the fact that we don't use gigs of memory any more will make up for it.&lt;br /&gt;I'm also thinking about distribution. EclipseFP came with Scion and Scion-browser bundled, if only because we used a different version of scion than the one on Hackage. I think that moving forward we'll rely on cabal install and Haskage. I'm going to add a simple interface to run cabal install inside EclipseFP, so you shouldn't have to go outside to install a package. So the EclipseFP preferences will just ask the user for the path to the buildwrapper and scion-browser executables, with an option to install them from hackage.&lt;br /&gt;&lt;br /&gt;If people want to start testing, just go on github, and grab the &lt;a href="https://github.com/JPMoresmau/BuildWrapper"&gt;BuildWrapper &lt;/a&gt;repository (main branch) and the EclipseFP project (&lt;a href="https://github.com/JPMoresmau/eclipsefp/tree/buildwrapper"&gt;buildwrapper branch&lt;/a&gt;). For the moment, BuildWrapper probably only builds on GHC 7.0. Once I have the feeling it's robust enough and there's no big flaw in the new architecture, I can work on enhancing portability.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/37404288-4732310666146341939?l=jpmoresmau.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jpmoresmau.blogspot.com/feeds/4732310666146341939/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=37404288&amp;postID=4732310666146341939' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/37404288/posts/default/4732310666146341939'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/37404288/posts/default/4732310666146341939'/><link rel='alternate' type='text/html' href='http://jpmoresmau.blogspot.com/2011/10/new-backend-for-eclipsefp.html' title='New backend for EclipseFP'/><author><name>JP Moresmau</name><uri>http://www.blogger.com/profile/09964251063221757176</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='26' height='32' src='http://4.bp.blogspot.com/_SFBL69b3jRQ/TIUvCsYa5EI/AAAAAAAAACw/4H33zrk1nAI/S220/shades.jpg'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-37404288.post-2269647870734466379</id><published>2011-09-02T16:56:00.002+02:00</published><updated>2011-09-02T16:59:49.767+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='self-publicity'/><category scheme='http://www.blogger.com/atom/ns#' term='Haskell'/><category scheme='http://www.blogger.com/atom/ns#' term='EclipseFP'/><title type='text'>EclipseFP 2.1.0 released!</title><content type='html'>&lt;span class="Apple-style-span" style="font-family: Verdana, sans-serif;"&gt;It's been a little while, but finally a new version of EclipseFP has been released! This version is mainly the work of Alejandro Serrano, who has worked on EclipseFP (and the underlying utilities) during his &lt;a href="http://serras-haskell-gsoc.blogspot.com/"&gt;GSoC project&lt;/a&gt;. There are lots of new features in that version, mainly :&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;span class="Apple-style-span" style="font-family: Verdana, sans-serif;"&gt;A package/module browser&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span class="Apple-style-span" style="font-family: Verdana, sans-serif;"&gt;Hoogle integration&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span class="Apple-style-span" style="font-family: Verdana, sans-serif;"&gt;Support for running tests&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span class="Apple-style-span" style="font-family: Verdana, sans-serif;"&gt;HLint warnings&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span class="Apple-style-span" style="font-family: Verdana, sans-serif;"&gt;Support for running executables and get profiling graphs&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span class="Apple-style-span" style="font-family: Verdana, sans-serif;"&gt;SourceGraph generation&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span class="Apple-style-span" style="font-family: Verdana, sans-serif;"&gt;Better auto completion information&lt;/span&gt;&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: Verdana, sans-serif;"&gt;Lots, I'm telling you. There are also fixes and internal enhancements that hopefully should make your life easier.&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: Verdana, sans-serif;"&gt;You can just run the &lt;a href="http://eclipsefp.sf.net/updates"&gt;update &lt;/a&gt;from your Eclipse IDE. You can find the full release notes &lt;a href="https://sourceforge.net/projects/eclipsefp/files/EclipseFP%202%20branch/2.1.0/"&gt;there&lt;/a&gt;.&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: Verdana, sans-serif;"&gt;Note that Alejandro has also created a new web site for EclipseFP, that you can find &lt;a href="http://eclipsefp.github.com/"&gt;there&lt;/a&gt;. Alejandro, big thanks for your hard work and your dedication!&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: Verdana, sans-serif;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: Verdana, sans-serif;"&gt;Any feedback is welcome, and of course bug reports and requests for enhancements!&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: Verdana, sans-serif;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: Verdana, sans-serif;"&gt;Happy Haskell hacking in Eclipse!&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/37404288-2269647870734466379?l=jpmoresmau.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jpmoresmau.blogspot.com/feeds/2269647870734466379/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=37404288&amp;postID=2269647870734466379' title='12 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/37404288/posts/default/2269647870734466379'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/37404288/posts/default/2269647870734466379'/><link rel='alternate' type='text/html' href='http://jpmoresmau.blogspot.com/2011/09/eclipsefp-210-released.html' title='EclipseFP 2.1.0 released!'/><author><name>JP Moresmau</name><uri>http://www.blogger.com/profile/09964251063221757176</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='26' height='32' src='http://4.bp.blogspot.com/_SFBL69b3jRQ/TIUvCsYa5EI/AAAAAAAAACw/4H33zrk1nAI/S220/shades.jpg'/></author><thr:total>12</thr:total></entry><entry><id>tag:blogger.com,1999:blog-37404288.post-7115894115927787084</id><published>2011-08-31T17:46:00.000+02:00</published><updated>2011-08-31T17:46:24.206+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Hoogle'/><category scheme='http://www.blogger.com/atom/ns#' term='Windows'/><category scheme='http://www.blogger.com/atom/ns#' term='Haskell'/><title type='text'>Hoogle Command Line on Windows</title><content type='html'>&lt;p&gt;The new upcoming version of EclipseFP will feature &lt;a href="http://www.haskell.org/hoogle/"&gt;Hoogle&lt;/a&gt; integration, thanks to the work of &lt;a href="http://serras-haskell-gsoc.blogspot.com/"&gt;Alejandro Serrano&lt;/a&gt;, so I was doing some testing on one of my Windows machine (yes, I'm a Haskell hacker and a Windows user, so what?)... No real problem using Hoogle via the command line, but since it does require some other things to be installed, I though I'd post them there for reference.&lt;/p&gt;&lt;p&gt;Unlike Cabal, Hoogle uses external tools for some of its operations. These tools are I'd say part of any self-respecting Unix distribution, but not of Windows. So you'll need:&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;b&gt;wget&lt;/b&gt;: &lt;a href="http://gnuwin32.sourceforge.net/packages/wget.htm"&gt;http://gnuwin32.sourceforge.net/packages/wget.htm&lt;/a&gt;&lt;br /&gt;At time of writing, the download page is &lt;a href="http://sourceforge.net/projects/gnuwin32/files/wget/1.11.4-1/wget-1.11.4-1-setup.exe/download"&gt;http://sourceforge.net/projects/gnuwin32/files/wget/1.11.4-1/wget-1.11.4-1-setup.exe/download&lt;/a&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;b&gt;gzip&lt;/b&gt;: &lt;a href="http://gnuwin32.sourceforge.net/packages/gzip.htm"&gt;http://gnuwin32.sourceforge.net/packages/gzip.htm&lt;/a&gt;&lt;br /&gt;At time of writing, the download page is  &lt;a href="http://sourceforge.net/projects/gnuwin32/files/gzip/1.3.12-1/gzip-1.3.12-1-setup.exe/download"&gt;http://sourceforge.net/projects/gnuwin32/files/gzip/1.3.12-1/gzip-1.3.12-1-setup.exe/download&lt;/a&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;b&gt;tar&lt;/b&gt;: &lt;a href="http://gnuwin32.sourceforge.net/packages/gtar.htm"&gt;http://gnuwin32.sourceforge.net/packages/gtar.htm&lt;/a&gt;&lt;br /&gt;At time of writing, the download page is &lt;a href="http://sourceforge.net/projects/gnuwin32/files/tar/1.13-1/tar-1.13-1-bin.exe/download"&gt;http://sourceforge.net/projects/gnuwin32/files/tar/1.13-1/tar-1.13-1-bin.exe/download&lt;/a&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;Install everything in the same directory and put the bin subdirectory in your PATH. &lt;code&gt;hoogle data&lt;/code&gt; should run fine.&lt;br /&gt;&lt;/p&gt;&lt;p&gt;Note also that since it's using wget, if you have an HTTP proxy you need to configure wget to use it (Cabal uses the internet explorer connection settings and finds the proxy settings from that). The files is &lt;code&gt;etc\wgetrc&lt;/code&gt; in the directory you installed wget, find the &lt;code&gt;http_proxy&lt;/code&gt; entry and adapt to your settings.&lt;br /&gt;&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/37404288-7115894115927787084?l=jpmoresmau.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jpmoresmau.blogspot.com/feeds/7115894115927787084/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=37404288&amp;postID=7115894115927787084' title='5 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/37404288/posts/default/7115894115927787084'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/37404288/posts/default/7115894115927787084'/><link rel='alternate' type='text/html' href='http://jpmoresmau.blogspot.com/2011/08/hoogle-command-line-on-windows.html' title='Hoogle Command Line on Windows'/><author><name>JP Moresmau</name><uri>http://www.blogger.com/profile/09964251063221757176</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='26' height='32' src='http://4.bp.blogspot.com/_SFBL69b3jRQ/TIUvCsYa5EI/AAAAAAAAACw/4H33zrk1nAI/S220/shades.jpg'/></author><thr:total>5</thr:total></entry><entry><id>tag:blogger.com,1999:blog-37404288.post-8290131478769134292</id><published>2011-06-24T11:50:00.001+02:00</published><updated>2011-06-24T11:52:21.124+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Cabal'/><category scheme='http://www.blogger.com/atom/ns#' term='GHC'/><category scheme='http://www.blogger.com/atom/ns#' term='Haskell'/><category scheme='http://www.blogger.com/atom/ns#' term='EclipseFP'/><title type='text'>EclipseFP: the way forward??</title><content type='html'>This is not the usual "hey I managed to get some code to work, check it out" blog post. Bear with me as I'm just thinking out loud. This is about EclipseFP and how we can move it forwards.&lt;br /&gt;&lt;br /&gt;At the moment EclipseFP works pretty well for simple, smallish Haskell projects. People have noted some performance issues on large projects, and part of it is the huge memory footprint of GHC when used through its API. After a couple of hours of working on a yesod project (so we're talking quasi quotation, template haskell, etc), the scion server takes 1Gb of memory... Restarting brings it back to reasonable levels, which seems to point to memory leaks in the GHC API.&lt;br /&gt;Maybe more critically, people are now asking for features that get increasingly harder to implement using Scion:&lt;br /&gt;- static GHC flags like -threaded (Nominolo's working on a version of Scion that could handle these)&lt;br /&gt;- C or HSC sources (or other kind of stuff requiring a preprocessor)&lt;br /&gt;- Having executables or test suites referencing the library component directly in the Cabal file&lt;br /&gt;&lt;br /&gt;The main thing with these is that Cabal handles them fine, so basically typing cabal build at the command prompt solves these issues, which undermines the usefulness of having an IDE in the first place... But they require more than just calling the GHC API: building and linking a library in-place, calling a c compiler, hsc2hs, etc...&lt;br /&gt;Of course Cabal publishes an API. So for example the code used by Cabal to build an in-place version of the library I could access, in theory, from Scion. But then Cabal calls the ghc executable, so the Cabal API gives me no easy way to get back errors from GHC, etc...&lt;br /&gt;&lt;br /&gt;What does accessing the GHC API gives us? An AST, that can be generated from an unsaved file (so you don't need to save your haskell source file to see your errors, our up to date outline, etc). All the rest (syntax highlighting, jump to definition, etc) could probably be done from the AST.&lt;br /&gt;&lt;br /&gt;So I'm wondering now if scrapping scion totally would not be a good idea. A rough outline of how things could work would be:&lt;br /&gt;- create a temp folder in which we will work, copy in it all the project files (sources, etc)&lt;br /&gt;- use cabal to build in that folder&lt;br /&gt;- parse cabal output to get errors and their location&lt;br /&gt;- unsaved files in the EclipseFP editor could have their unsaved contents copied into that folder (that folder represent the current state of the project, which may not be what is really saved on disk)&lt;br /&gt;- have only a simple Haskell executable that given a module file, loads it using all the built files in the temp folder, and return the AST in some easy to parse format. Firing and getting the result would ensure GHC cannot grab loads of memory and not release it&lt;br /&gt;- the IDE code then gets the AST and does all it needs to it&lt;br /&gt;- the AST could even be saved in that temp folder in some format, so that the Java code would only request it when the original file is more recent, which would allow easy parsing of dependent modules AST (for example to retrieve all the symbols exported, etc)&lt;br /&gt;&lt;br /&gt;There are a lot of ugly bits in there, maybe, but that would solve my problems... I suppose all of that could be written in Haskell and we could keep a similar enough API to scion, so that the Java code wouldn't need change too much...&lt;br /&gt;&lt;br /&gt;For the moment I'm not going to reach into things anyway, but if anybody has some feedback, I'll gladly take any opinion on board!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/37404288-8290131478769134292?l=jpmoresmau.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jpmoresmau.blogspot.com/feeds/8290131478769134292/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=37404288&amp;postID=8290131478769134292' title='6 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/37404288/posts/default/8290131478769134292'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/37404288/posts/default/8290131478769134292'/><link rel='alternate' type='text/html' href='http://jpmoresmau.blogspot.com/2011/06/eclipsefp-way-forward.html' title='EclipseFP: the way forward??'/><author><name>JP Moresmau</name><uri>http://www.blogger.com/profile/09964251063221757176</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='26' height='32' src='http://4.bp.blogspot.com/_SFBL69b3jRQ/TIUvCsYa5EI/AAAAAAAAACw/4H33zrk1nAI/S220/shades.jpg'/></author><thr:total>6</thr:total></entry><entry><id>tag:blogger.com,1999:blog-37404288.post-382206280175773269</id><published>2011-05-22T20:17:00.000+02:00</published><updated>2011-05-22T20:17:44.378+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Java'/><category scheme='http://www.blogger.com/atom/ns#' term='SWT'/><category scheme='http://www.blogger.com/atom/ns#' term='GUI'/><category scheme='http://www.blogger.com/atom/ns#' term='Haskell'/><title type='text'>Haskell + FFI + Java + SWT: crazy, maybe, but working!</title><content type='html'>A few years ago &lt;a href="http://jpmoresmau.blogspot.com/2007/04/haskell-code-java-ui.html"&gt;I noted&lt;/a&gt; that being able to mix Haskell code and a Java GUI might be a good idea, since Java UIs have matured enormously, and Haskell UI library are still struggling to gain wide adoption, &lt;a href="http://www.mail-archive.com/haskell-cafe@haskell.org/msg89892.html"&gt;a recent thread &lt;/a&gt;on cafe being proof. &lt;a href="http://www.mail-archive.com/haskell-cafe@haskell.org/msg67596.html"&gt;SWT bindings&lt;/a&gt; were mentioned, so I had a look at both the Java and the C SWT code, for windows. Two immediate things sprang to view:&lt;br /&gt;1. The SWT C library is using JNI, duh. It relies on JNI for some operations so you can't just use the SWT.dll in your haskell code that easily&lt;br /&gt;2. The SWT C bindings are very low level, and there is a wealth of Java code on top of that to provide a lot ow glue and boilerplate code for all kind of widgets, and it would be long and painful to rewrite it all in Haskell.&lt;br /&gt;&lt;br /&gt;My Java to Haskell code converter only being a dream at the moment (one day...), the next reasonable (ahem) option was then obvious: start a few blown JVM from Haskell and use it to drive SWT classes.&lt;br /&gt;I'm a Java expert, I can say, and my Haskell is slowly coming on, but the glue in between has to be C, so it wasn't a smooth ride, but I finally got it working! So what's happening is this:&lt;br /&gt;- The Haskell applications starts as they all do, in a main :: IO() function&lt;br /&gt;- Haskell invokes some C code that starts a new JVM, passing it a classpath. The C code acts then as a facade hiding some of the intricacies of accessing the JVM&lt;br /&gt;- Haskell uses the foreign C functions to create ands manipulate the SWT Java objects&lt;br /&gt;- I even got callbacks working, meaning you can register a Haskell listener on a SWT button, and hence have Haskell code calculate the results of that button click.&lt;br /&gt;&lt;br /&gt;And I have proof! Here's a simple SWT Shell with one button:&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://4.bp.blogspot.com/-oNdRjM8qwzI/TdlSFxKnThI/AAAAAAAAADY/Wyf0mfwVfkM/s1600/TestButton0.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://4.bp.blogspot.com/-oNdRjM8qwzI/TdlSFxKnThI/AAAAAAAAADY/Wyf0mfwVfkM/s1600/TestButton0.png" /&gt;&lt;/a&gt;&lt;/div&gt;When you click the button:&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://3.bp.blogspot.com/-bAf_p9sO4_0/TdlSGeMiWfI/AAAAAAAAADc/IFkISWDjMOA/s1600/TestButton1.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://3.bp.blogspot.com/-bAf_p9sO4_0/TdlSGeMiWfI/AAAAAAAAADc/IFkISWDjMOA/s1600/TestButton1.png" /&gt;&lt;/a&gt;&lt;/div&gt;And the handler for the button click is written in Haskell (I have a MVar called count for the number of times the user clicked):&lt;br /&gt;&lt;pre&gt;do&lt;br /&gt;    modifyMVar count (\c-&amp;gt;do&lt;br /&gt;        let nc=c+1&lt;br /&gt;        let s=if nc==1 then "once." else ((show nc)++ " times.")&lt;br /&gt;        text3&amp;lt;-toJString ("Clicked "++s)&lt;br /&gt;        voidMethod button "setText" "(Ljava/lang/String;)V" [JObj text3]&lt;br /&gt;        return(nc,())&lt;br /&gt;        )&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;You can see here the invocation of the setText method of the SWT Button, which for the moment requires knowing the exact JNI signature, and the translation from Haskell strings to Java strings.&lt;br /&gt;&lt;br /&gt;Of course, there is still loads to do. I probably need to automatically generate bindings to the Java objects to simplify greatly their manipulation, wrap stateful operations in a monad, etc. But this may open a new way for Haskell GUI. Or it may just be a crazy idea that has already taught me a lot about FFI and JNI...&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/37404288-382206280175773269?l=jpmoresmau.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jpmoresmau.blogspot.com/feeds/382206280175773269/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=37404288&amp;postID=382206280175773269' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/37404288/posts/default/382206280175773269'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/37404288/posts/default/382206280175773269'/><link rel='alternate' type='text/html' href='http://jpmoresmau.blogspot.com/2011/05/haskell-ffi-java-swt-crazy-maybe-but.html' title='Haskell + FFI + Java + SWT: crazy, maybe, but working!'/><author><name>JP Moresmau</name><uri>http://www.blogger.com/profile/09964251063221757176</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='26' height='32' src='http://4.bp.blogspot.com/_SFBL69b3jRQ/TIUvCsYa5EI/AAAAAAAAACw/4H33zrk1nAI/S220/shades.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://4.bp.blogspot.com/-oNdRjM8qwzI/TdlSFxKnThI/AAAAAAAAADY/Wyf0mfwVfkM/s72-c/TestButton0.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-37404288.post-8491891952688163965</id><published>2011-04-18T20:26:00.000+02:00</published><updated>2011-04-18T20:26:15.277+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='JavaScript'/><category scheme='http://www.blogger.com/atom/ns#' term='games'/><category scheme='http://www.blogger.com/atom/ns#' term='self-publicity'/><category scheme='http://www.blogger.com/atom/ns#' term='Haskell'/><title type='text'>Pirates 0.2: fixes and a chat interface</title><content type='html'>I released a little update to my Pirates Yesod/Canvas game. Nothing too dramatic, but the new version, still at&amp;nbsp;&lt;a href="http://pirates.dyndns-free.com/"&gt;http://pirates.dyndns-free.com&lt;/a&gt;&amp;nbsp;boasts:&lt;br /&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Fixes in the collision detection code&lt;/li&gt;&lt;li&gt;A chat interface, so you can talk to the other ship you're fighting with. Stock up on pirates insults!&lt;/li&gt;&lt;li&gt;Fixes in handling of games when a ship leaves the game before it's finished&lt;/li&gt;&lt;/ul&gt;&lt;div&gt;As I said, nothing too fancy, but I find that polishing off bugs and adding unplanned features is often a good exercise, especially for personal projects where the temptation is great to just move to something else when it kinda works. The chat interface was interesting: the server side code was done in a few minutes, using the same event system as the rest, but I struggled longer with the HTML to get the right positions for everything, as usual... Now it's on the right hand side, outside of the canvas area, which makes the full game area much bigger than the original 800x600, but I don't think I get a lot of mobile users anyways (-;.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;I could probably make the game more appealing long term by having a bigger area where more than 2 ships could battle, and have more of a RPG feel to it (maybe be able to log in and out so you keep your ship, be able to repair it in harbours, etc...). I'll see what I have time to do. Any suggestions welcome!&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/37404288-8491891952688163965?l=jpmoresmau.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jpmoresmau.blogspot.com/feeds/8491891952688163965/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=37404288&amp;postID=8491891952688163965' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/37404288/posts/default/8491891952688163965'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/37404288/posts/default/8491891952688163965'/><link rel='alternate' type='text/html' href='http://jpmoresmau.blogspot.com/2011/04/pirates-02-fixes-and-chat-interface.html' title='Pirates 0.2: fixes and a chat interface'/><author><name>JP Moresmau</name><uri>http://www.blogger.com/profile/09964251063221757176</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='26' height='32' src='http://4.bp.blogspot.com/_SFBL69b3jRQ/TIUvCsYa5EI/AAAAAAAAACw/4H33zrk1nAI/S220/shades.jpg'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-37404288.post-8135660991591348808</id><published>2011-04-08T14:12:00.000+02:00</published><updated>2011-04-08T14:12:12.216+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='games'/><category scheme='http://www.blogger.com/atom/ns#' term='self-publicity'/><category scheme='http://www.blogger.com/atom/ns#' term='Haskell'/><title type='text'>Pirates!! A multi-player browser game with Yesod and Canvas</title><content type='html'>&lt;span class="Apple-style-span" style="font-family: inherit;"&gt;I can finally open to the public a little game I've made! You can now go to&amp;nbsp;&lt;a href="http://pirates.dyndns-free.com/"&gt;http://pirates.dyndns-free.com&lt;/a&gt;&amp;nbsp;and play!&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: inherit;"&gt;The game is simple: you're sailing a pirate ship, and you have to sink your opponent. You can use cannons, ram the other ship, board it with your blood-thirsty crew. Your speed depends of course on the direction and strength of the wind. You can play alone versus a very dumb AI (mainly to get the hang of the controls), against a friend in a private game, or against any dog on the internet.&amp;nbsp;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: inherit;"&gt;The technology stack is as follows:&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Hosting is on a free Amazon EC2 instance. Performance is probably not going to be great, but should be sufficient I hope for the traffic I'll be getting!&lt;/li&gt;&lt;li&gt;Server side is &lt;a href="http://www.yesodweb.com/"&gt;Yesod &lt;/a&gt;0.7. Coming from the Java/JSP/Struts world it was such a pleasure to work in Haskell, with type safe templates. I have no web server, just warp, since there are very few static files (a few sprites and the tile image).&lt;/li&gt;&lt;li&gt;Client side uses &lt;a href="https://developer.mozilla.org/en/canvas_tutorial"&gt;Canvas &lt;/a&gt;with a sprinkling of &lt;a href="http://jquery.org/"&gt;JQuery&lt;/a&gt;.&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: inherit;"&gt;As you can see, no database. Information about current games is purely in memory, and I don't keep any long term information about players. I suppose that allowing players to log in with their Google or Facebook id, and keep statistics on their battles would be good, but I'm not sure this little game will get enough traction to warrant it, really...&amp;nbsp;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: inherit;"&gt;The AI also is not great shake, there are only two bots: The Sitting Duck turns to face the wind and stays there. The Drunken Sailor just goes randomly through all possible actions. But hey, it's a multi-player game!&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: inherit;"&gt;I'm not too sure if I chose the best route for concurrency. I use &lt;a href="http://www.haskell.org/ghc/docs/latest/html/libraries/base-4.3.1.0/Control-Concurrent-MVar.html"&gt;MVars &lt;/a&gt;and&amp;nbsp;modifyMVar.&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: inherit;"&gt;In fact the more difficult bit was to design the control. I didn't want to a do a full 3D environment, and opted for a top view, but the velocity of the ships was essential, and so providing just direction keys as in more static games wouldn't have worked. Hopefully the way the control works, being disposed on a copy of the boat icon at the top of screen, that turns when you boat turns, will work well. The icons are probably a bit small, it's fine for a mouse but I don't think it could work on a touch screen, unless you have tiny fingers.&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: inherit;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;A little bit of personal info: inspiration from this game comes from the French magazine "Jeux et Stratégies", that my dad used to get when I was young, and that got me into games. We have still kept all the issues, and issue 22 from August 1983 describes a simple ship battle game, rules written by &lt;a href="http://www.legrog.org/biographies/michel-brassinne"&gt;Michel Brassinne&lt;/a&gt;&amp;nbsp;(French warning!). Thanks!&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: inherit;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: inherit;"&gt;Still it was fun to do!! Hope you enjoy playing it a little!&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/37404288-8135660991591348808?l=jpmoresmau.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jpmoresmau.blogspot.com/feeds/8135660991591348808/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=37404288&amp;postID=8135660991591348808' title='5 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/37404288/posts/default/8135660991591348808'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/37404288/posts/default/8135660991591348808'/><link rel='alternate' type='text/html' href='http://jpmoresmau.blogspot.com/2011/04/pirates-multi-player-browser-game-with.html' title='Pirates!! A multi-player browser game with Yesod and Canvas'/><author><name>JP Moresmau</name><uri>http://www.blogger.com/profile/09964251063221757176</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='26' height='32' src='http://4.bp.blogspot.com/_SFBL69b3jRQ/TIUvCsYa5EI/AAAAAAAAACw/4H33zrk1nAI/S220/shades.jpg'/></author><thr:total>5</thr:total></entry><entry><id>tag:blogger.com,1999:blog-37404288.post-9207917087393061196</id><published>2011-04-01T16:03:00.001+02:00</published><updated>2011-04-06T20:17:40.006+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Linux'/><category scheme='http://www.blogger.com/atom/ns#' term='Haskell'/><title type='text'>Install GHC7 and Yesod on Amazon Linux</title><content type='html'>I've been working lately on a multi-player web game, to actually get to know &lt;a href="https://developer.mozilla.org/en/canvas_tutorial"&gt;HTML Canvas&lt;/a&gt; (on the client) and &lt;a href="http://www.yesodweb.com/"&gt;Yesod &lt;/a&gt;(on the server) properly. I have a first fully functional version of the game, so now is the time to think about hosting. Michael initiated a discussion about it, and in the meantime I decided to investigate Amazon since they offer &lt;a href="http://aws.amazon.com/free/"&gt;free instances&lt;/a&gt; now on EC2.&lt;br /&gt;The free AMIs (images) come with a version of Linux &lt;a href="http://aws.amazon.com/amazon-linux-ami/"&gt;specific to Amazon&lt;/a&gt;, but apparently &lt;a href="http://www.cloudave.com/4872/open-source-and-cloud-computing-the-amazon-linux-ami-is-now-available/"&gt;binary compatible with CentOS&lt;/a&gt;, on which GHC and the Haskell Platform have been reported to &lt;a href="http://klevstul.posterous.com/haskell-ghc-702-on-centos-55"&gt;successfully build&lt;/a&gt;.&lt;br /&gt;These are the steps I followed to get everything working, hopefully they can be useful to somebody else. So as per the Amazon &lt;a href="http://docs.amazonwebservices.com/AWSEC2/latest/GettingStartedGuide/"&gt;Getting Started guide&lt;/a&gt;, you connect to your instance with the ec2-user.&lt;br /&gt;First we install through the package manager some useful packages:&lt;br /&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;sudo yum install make&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;sudo yum install gcc&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;sudo yum install zlib-devel&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;sudo yum install glut&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;sudo yum install glut-devel&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;I didn't find &lt;a href="http://gmplib.org/"&gt;gmp&lt;/a&gt;, so I downloaded and installed in the default location:&lt;br /&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;curl -O ftp://ftp.gnu.org/gnu/gmp/gmp-4.3.2.tar.bz2&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;tar -xjvf gmp-4.3.2.tar.bz2&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;cd gmp-4.3.2&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;./configure&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;make&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;sudo make install&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;But afterwards I had issues building some Haskell packages because it didn't like the default install folder of /usr/local/lib, it preferred /usr/lib, so I did:&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;sudo cp /usr/local/lib/libgmp.* /usr/lib/&lt;/span&gt;&lt;br /&gt;But I suppose &lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;./configure --prefix=/usr/lib/&lt;/span&gt; would be the preferred way to do that.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://libbsd.freedesktop.org/wiki/"&gt;Libbsd &lt;/a&gt;is also required otherwise unix-compat fails:&lt;br /&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;curl -O http://libbsd.freedesktop.org/releases/libbsd-0.2.0.tar.gz&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;tar -xzvf libbsd-0.2.0.tar.gz&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;cd libbsd-0.2.0&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;sudo make install&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Then for GHC, I just downloaded the &lt;a href="http://haskell.org/ghc/download_ghc_7_0_2#distros"&gt;generic binary&lt;/a&gt; and installed that. I decided to install Haskell under my home folder.&lt;br /&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;curl -O http://haskell.org/ghc/dist/7.0.2/ghc-7.0.2-i386-unknown-linux.tar.bz2&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;tar -xjvf ghc-7.0.2-i386-unknown-linux.tar.bz2&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;cd ghc-7.0.2&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;./configure --prefix=/home/ec2-user/haskell&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;make install&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Make sure we know how to find it:&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;export PATH=$PATH:/home/ec2-user/haskell/bin&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Then get the &lt;a href="http://hackage.haskell.org/platform/linux.html"&gt;Haskell Platform source&lt;/a&gt; and build that, since there is no binary (yet) for our platform:&lt;br /&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;curl -O http://lambda.galois.com/hp-tmp/2011.2.0.0/haskell-platform-2011.2.0.0.tar.gz&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;tar -xzvf haskell-platform-2011.2.0.0.tar.gz&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;cd haskell-platform-2011.2.0.0&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;./configure --prefix=/home/ec2-user/haskell&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;make&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;make install&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Once you're there, it's back to familiar ground:&lt;br /&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;cabal update&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;cabal install yesod&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;And there we are!! My deployment platform is ready!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/37404288-9207917087393061196?l=jpmoresmau.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jpmoresmau.blogspot.com/feeds/9207917087393061196/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=37404288&amp;postID=9207917087393061196' title='5 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/37404288/posts/default/9207917087393061196'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/37404288/posts/default/9207917087393061196'/><link rel='alternate' type='text/html' href='http://jpmoresmau.blogspot.com/2011/04/install-ghc7-and-yesod-on-amazon-linux.html' title='Install GHC7 and Yesod on Amazon Linux'/><author><name>JP Moresmau</name><uri>http://www.blogger.com/profile/09964251063221757176</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='26' height='32' src='http://4.bp.blogspot.com/_SFBL69b3jRQ/TIUvCsYa5EI/AAAAAAAAACw/4H33zrk1nAI/S220/shades.jpg'/></author><thr:total>5</thr:total></entry><entry><id>tag:blogger.com,1999:blog-37404288.post-1919730877766738959</id><published>2011-03-21T19:41:00.000+01:00</published><updated>2011-03-21T19:41:55.029+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Eclipse'/><category scheme='http://www.blogger.com/atom/ns#' term='self-publicity'/><category scheme='http://www.blogger.com/atom/ns#' term='Haskell'/><category scheme='http://www.blogger.com/atom/ns#' term='EclipseFP'/><title type='text'>EclipseFP 2.0.4 released: supports GHC 7!</title><content type='html'>&lt;span class="Apple-style-span" style="font-family: 'Helvetica Neue', Arial, Helvetica, sans-serif;"&gt;Hello, the demand was HUGE (well, everything is relative :-)) for a version of EclipseFP that could build and run on GHC7. Since the 2.0.3 release there is now a &lt;a href="http://hackage.haskell.org/platform/"&gt;Haskell Platform&lt;/a&gt; release that contains GHC7, so we had no excuse... And there it is! Thanks have to go mainly to&amp;nbsp;Alejandro Serrano, for getting Scion to compile with GHC7 and to&amp;nbsp;&lt;span class="Apple-style-span" style="-webkit-border-horizontal-spacing: 2px; -webkit-border-vertical-spacing: 2px; line-height: 18px;"&gt;&lt;a href="http://hackage.haskell.org/package/ghc-syb-utils"&gt;Thomas Schilling&lt;/a&gt; and&amp;nbsp;&lt;/span&gt;&lt;span class="Apple-style-span" style="-webkit-border-horizontal-spacing: 2px; -webkit-border-vertical-spacing: 2px; line-height: 18px;"&gt;&lt;a href="http://hackage.haskell.org/package/list-tries"&gt;Matti Niemenmaa&lt;/a&gt;, who upgraded their libraries for GHC7.&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: 'Helvetica Neue', Arial, Helvetica, sans-serif;"&gt;&lt;span class="Apple-style-span" style="-webkit-border-horizontal-spacing: 2px; -webkit-border-vertical-spacing: 2px; line-height: 18px;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: 'Helvetica Neue', Arial, Helvetica, sans-serif;"&gt;&lt;span class="Apple-style-span" style="-webkit-border-horizontal-spacing: 2px; -webkit-border-vertical-spacing: 2px; line-height: 18px;"&gt;So what we have is a scion backend that should build both with 6.12 and 7.0, and hopefully work the same on both. We now support test-suite sections in Cabal files, with limited support for running test suites (running just cabal test with no options).&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: 'Helvetica Neue', Arial, Helvetica, sans-serif;"&gt;&lt;span class="Apple-style-span" style="-webkit-border-horizontal-spacing: 2px; -webkit-border-vertical-spacing: 2px; line-height: 18px;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: 'Helvetica Neue', Arial, Helvetica, sans-serif;"&gt;&lt;span class="Apple-style-span" style="-webkit-border-horizontal-spacing: 2px; -webkit-border-vertical-spacing: 2px; line-height: 18px;"&gt;On my To Do list are full support for test-suites (having full launch configurations for Cabal defined tests) and HLint integration. But I'd also like to work on my own project, so don't expect that a release every two weeks is going to be our normal cruising speed.&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: 'Helvetica Neue', Arial, Helvetica, sans-serif;"&gt;&lt;span class="Apple-style-span" style="-webkit-border-horizontal-spacing: 2px; -webkit-border-vertical-spacing: 2px; line-height: 18px;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: 'Helvetica Neue', Arial, Helvetica, sans-serif;"&gt;&lt;span class="Apple-style-span" style="-webkit-border-horizontal-spacing: 2px; -webkit-border-vertical-spacing: 2px; line-height: 18px;"&gt;As usual, just install from the Eclipse update site:&amp;nbsp;&lt;a href="http://eclipsefp.sf.net/updates"&gt;http://eclipsefp.sf.net/updates&lt;/a&gt;, and bug reports or feature requests should go to the &lt;a href="http://sourceforge.net/projects/eclipsefp/forums/forum/371922"&gt;SourceForge forum&lt;/a&gt; or the &lt;a href="http://sourceforge.net/mail/?group_id=108233"&gt;development mailing list&lt;/a&gt;.&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: 'Helvetica Neue', Arial, Helvetica, sans-serif;"&gt;&lt;span class="Apple-style-span" style="-webkit-border-horizontal-spacing: 2px; -webkit-border-vertical-spacing: 2px; line-height: 18px;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: 'Helvetica Neue', Arial, Helvetica, sans-serif;"&gt;&lt;span class="Apple-style-span" style="-webkit-border-horizontal-spacing: 2px; -webkit-border-vertical-spacing: 2px; line-height: 18px;"&gt;Happy Haskell Hacking!&lt;/span&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/37404288-1919730877766738959?l=jpmoresmau.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jpmoresmau.blogspot.com/feeds/1919730877766738959/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=37404288&amp;postID=1919730877766738959' title='16 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/37404288/posts/default/1919730877766738959'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/37404288/posts/default/1919730877766738959'/><link rel='alternate' type='text/html' href='http://jpmoresmau.blogspot.com/2011/03/eclipsefp-204-released-supports-ghc-7.html' title='EclipseFP 2.0.4 released: supports GHC 7!'/><author><name>JP Moresmau</name><uri>http://www.blogger.com/profile/09964251063221757176</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='26' height='32' src='http://4.bp.blogspot.com/_SFBL69b3jRQ/TIUvCsYa5EI/AAAAAAAAACw/4H33zrk1nAI/S220/shades.jpg'/></author><thr:total>16</thr:total></entry><entry><id>tag:blogger.com,1999:blog-37404288.post-4061746287560760004</id><published>2011-03-07T19:34:00.002+01:00</published><updated>2011-03-07T19:35:45.781+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='IDE'/><category scheme='http://www.blogger.com/atom/ns#' term='self-publicity'/><category scheme='http://www.blogger.com/atom/ns#' term='Haskell'/><category scheme='http://www.blogger.com/atom/ns#' term='EclipseFP'/><title type='text'>EclipseFP 2.0.3 released</title><content type='html'>It's my pleasure to release EclipseFP version 2.0.3. EclipseFP is a set of Eclipse plugins for Haskell development. Scooter and I have tried to add a few features and hopefully to fix the bugs that were reported by users.&lt;br /&gt;&lt;br /&gt;Main things in this version are code completion templates, which enables you to code even quicker!! We also enhanced the Cabal support (you can now set Cabal flags from the project properties, run Cabal install on the project) and simplified the installation (more settings are auto detected).&lt;br /&gt;&lt;br /&gt;EclipseFP is alive and well (I use it for all my Haskell work) so please send us all your feedback, bug reports, feature requests!&lt;br /&gt;&lt;br /&gt;Use the standard Eclipse &lt;a href="http://eclipsefp.sf.net/updates"&gt;Updates Site&lt;/a&gt; &amp;nbsp;or &lt;a href="https://sourceforge.net/projects/eclipsefp/files/EclipseFP%202%20branch/2.0.3/"&gt;download files&lt;/a&gt;. Enjoy!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/37404288-4061746287560760004?l=jpmoresmau.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jpmoresmau.blogspot.com/feeds/4061746287560760004/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=37404288&amp;postID=4061746287560760004' title='8 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/37404288/posts/default/4061746287560760004'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/37404288/posts/default/4061746287560760004'/><link rel='alternate' type='text/html' href='http://jpmoresmau.blogspot.com/2011/03/eclipse-203-released.html' title='EclipseFP 2.0.3 released'/><author><name>JP Moresmau</name><uri>http://www.blogger.com/profile/09964251063221757176</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='26' height='32' src='http://4.bp.blogspot.com/_SFBL69b3jRQ/TIUvCsYa5EI/AAAAAAAAACw/4H33zrk1nAI/S220/shades.jpg'/></author><thr:total>8</thr:total></entry><entry><id>tag:blogger.com,1999:blog-37404288.post-3561447253424488690</id><published>2011-01-21T15:10:00.002+01:00</published><updated>2011-01-21T15:13:49.121+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Artificial Intelligence'/><category scheme='http://www.blogger.com/atom/ns#' term='Genetic Programming'/><category scheme='http://www.blogger.com/atom/ns#' term='Haskell'/><title type='text'>Evolving a computer with TECS and Genprog</title><content type='html'>I've started reading &lt;a href="http://www.idc.ac.il/tecs/"&gt;The Elements of Computer Systems&lt;/a&gt; since it was recommended on &lt;a href="http://www.reddit.com/r/programming/comments/f11nl/tecs_the_most_amazing_cs_course_in_one_semester/"&gt;Reddit&lt;/a&gt; and it's a great read. After the section on boolean gates I decided to have a quick go at build the gates in Haskell. Just implement Nand with pattern matching, and implement all the other gates just in term of functions calls to previously defined gates. The book mentioned "think positive" about implementing Not, so I just T as the second parameter, did't think more about it, even though I wasn't sure having a constant value was OK.&lt;br /&gt;&lt;br /&gt;&lt;script src="https://gist.github.com/789706.js"&gt; &lt;/script&gt;&lt;br /&gt;&lt;br /&gt;Then I moved on to the other gates. It was interesting to think about boolean logic without Or, for example, after years of only reasoning in terms of And Or and Not. But at some stage I thought "why am I doing this by hand?". I remembered a thread about a &lt;a href="http://article.gmane.org/gmane.comp.lang.haskell.general/18322"&gt;new genetic programming library on an Haskell group&lt;/a&gt;. Surely generating the gates would be simple enough?&lt;br /&gt;So I got &lt;a href="http://hackage.haskell.org/package/genprog"&gt;genprog &lt;/a&gt;from hackage, and adapted the example for my needs. I started with a very simple system to determine the implementation of Not:&lt;br /&gt;&lt;br /&gt;&lt;script src="https://gist.github.com/789711.js"&gt; &lt;/script&gt;&lt;br /&gt;&lt;br /&gt;And of course, the result came quickly enough: not a=nand(a,a). No need for a Const at all! Evolution has beaten me! (OK, I'm only a not-so-intelligent designer, I suppose...)&lt;br /&gt;Now, I'm going to see if this approach can take me all the way to the arithmetic unit...&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/37404288-3561447253424488690?l=jpmoresmau.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jpmoresmau.blogspot.com/feeds/3561447253424488690/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=37404288&amp;postID=3561447253424488690' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/37404288/posts/default/3561447253424488690'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/37404288/posts/default/3561447253424488690'/><link rel='alternate' type='text/html' href='http://jpmoresmau.blogspot.com/2011/01/evolving-computer-with-tecs-and-genprog.html' title='Evolving a computer with TECS and Genprog'/><author><name>JP Moresmau</name><uri>http://www.blogger.com/profile/09964251063221757176</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='26' height='32' src='http://4.bp.blogspot.com/_SFBL69b3jRQ/TIUvCsYa5EI/AAAAAAAAACw/4H33zrk1nAI/S220/shades.jpg'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-37404288.post-2401586438447870739</id><published>2010-12-01T17:00:00.002+01:00</published><updated>2010-12-02T15:57:25.490+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='IDE'/><category scheme='http://www.blogger.com/atom/ns#' term='Eclipse'/><category scheme='http://www.blogger.com/atom/ns#' term='self-publicity'/><category scheme='http://www.blogger.com/atom/ns#' term='Haskell'/><title type='text'>EclipseFP 2.0.2 released</title><content type='html'>&lt;span class="Apple-style-span" style="font-family: 'Helvetica Neue', Arial, Helvetica, sans-serif;"&gt;I am pleased to announce another release of &lt;a href="http://eclipsefp.sourceforge.net/"&gt;EclipseFP&lt;/a&gt;. Version 2.0.2 should make installation of Scion easier, improve stability and performance of the parsing and building operations, and provide a few new functionalities. You can now configure where the "Open Definition" action will look for definitions (these can be in Haskell source code or Haddock pages): by default it will look in the dependent projects, in your GHC install doc folder, and on &lt;a href="http://hackage.haskell.org/packages/archive/pkg-list.html"&gt;Hackage&lt;/a&gt;, but you can add more locations in the preferences.&amp;nbsp;You can also generate source distribution via a project export command (that calls cabal sdist).&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: 'Helvetica Neue', Arial, Helvetica, sans-serif;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: 'Helvetica Neue', Arial, Helvetica, sans-serif;"&gt;The release notes are &lt;a href="https://sourceforge.net/projects/eclipsefp/files/EclipseFP%202%20branch/2.0.2/net.sf.eclipsefp.haskell_2.0.2.txt/download"&gt;here&lt;/a&gt;. To install or upgrade, just point your Eclipse to&amp;nbsp;&lt;span class="Apple-style-span" style="-webkit-border-horizontal-spacing: 5px; -webkit-border-vertical-spacing: 5px;"&gt;&lt;a href="http://eclipsefp.sf.net/updates"&gt;http://eclipsefp.sf.net/updates&lt;/a&gt;. Be sure to configure both the GHC path and the Cabal path in the preferences.&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: 'Helvetica Neue', Arial, Helvetica, sans-serif;"&gt;&lt;span class="Apple-style-span" style="-webkit-border-horizontal-spacing: 5px; -webkit-border-vertical-spacing: 5px;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: 'Helvetica Neue', Arial, Helvetica, sans-serif;"&gt;&lt;span class="Apple-style-span" style="-webkit-border-horizontal-spacing: 5px; -webkit-border-vertical-spacing: 5px;"&gt;Happy Haskell hacking!&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, mono; font-size: small;"&gt;&lt;span class="Apple-style-span" style="-webkit-border-horizontal-spacing: 5px; -webkit-border-vertical-spacing: 5px; font-size: 13px;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/37404288-2401586438447870739?l=jpmoresmau.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jpmoresmau.blogspot.com/feeds/2401586438447870739/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=37404288&amp;postID=2401586438447870739' title='10 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/37404288/posts/default/2401586438447870739'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/37404288/posts/default/2401586438447870739'/><link rel='alternate' type='text/html' href='http://jpmoresmau.blogspot.com/2010/12/eclipse-202-released.html' title='EclipseFP 2.0.2 released'/><author><name>JP Moresmau</name><uri>http://www.blogger.com/profile/09964251063221757176</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='26' height='32' src='http://4.bp.blogspot.com/_SFBL69b3jRQ/TIUvCsYa5EI/AAAAAAAAACw/4H33zrk1nAI/S220/shades.jpg'/></author><thr:total>10</thr:total></entry><entry><id>tag:blogger.com,1999:blog-37404288.post-4049228303107344542</id><published>2010-11-25T20:07:00.000+01:00</published><updated>2010-11-25T20:07:28.739+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='games'/><category scheme='http://www.blogger.com/atom/ns#' term='self-publicity'/><category scheme='http://www.blogger.com/atom/ns#' term='GUI'/><category scheme='http://www.blogger.com/atom/ns#' term='Haskell'/><title type='text'>A simple game in Haskell + SDL</title><content type='html'>&lt;span class="Apple-style-span" style="font-family: 'Helvetica Neue', Arial, Helvetica, sans-serif;"&gt;I wanted to play a bit with &lt;a href="http://www.libsdl.org/"&gt;SDL&lt;/a&gt;, and it's always good to step away from actually working on &lt;a href="http://eclipsefp.sourceforge.net/"&gt;EclipseFP&lt;/a&gt; to use it for a "real" project. So I wrote a very primitive game using &lt;a href="http://hackage.haskell.org/package/SDL"&gt;SDL&lt;/a&gt; and &lt;a href="http://hackage.haskell.org/package/SDL-ttf"&gt;SDL_TTF&lt;/a&gt;. It's a typing speed game (hence the, ahem, clever pun on the name: &lt;a href="http://hackage.haskell.org/package/TypeClass"&gt;TypeClass&lt;/a&gt;): you see letters scrolling down the screen and you need to type them, and of course they go faster and faster. Maybe my children will learn to type with it. Maybe not.&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: 'Helvetica Neue', Arial, Helvetica, sans-serif;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: 'Helvetica Neue', Arial, Helvetica, sans-serif;"&gt;I had SDL installed earlier, but of course SDL_TTF proved challenging on my windows machine, but I think it's was all my fault, I probably didn't read the instructions properly or something. Anyway, I only forgotten to set the LIBS variable. When I ran export &lt;/span&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;LIBS=/usr/local/lib/libSDL_ttf.dll.a&lt;/span&gt;&lt;span class="Apple-style-span" style="font-family: 'Helvetica Neue', Arial, Helvetica, sans-serif;"&gt; in my MSYS environment then configure worked fine!&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: 'Helvetica Neue', Arial, Helvetica, sans-serif;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: 'Helvetica Neue', Arial, Helvetica, sans-serif;"&gt;Afterwards it was all plain sailing, really. Just remember to add &lt;/span&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;a href="http://hackage.haskell.org/packages/archive/SDL/0.6.2/doc/html/Graphics-UI-SDL-Events.html#v:enableUnicode"&gt;enableUnicode &lt;/a&gt;True&lt;/span&gt;&lt;span class="Apple-style-span" style="font-family: 'Helvetica Neue', Arial, Helvetica, sans-serif;"&gt; in your initialization code so you can get the actual Unicode character typed (I'm on a French keyboard, so typing M gives me the SDL key ;). And of course you need a font file, so I include a &lt;a href="http://www.gnu.org/software/freefont/"&gt;GNU FreeFont&lt;/a&gt; file with the package. It needs to be in the same folder as the executable.&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: 'Helvetica Neue', Arial, Helvetica, sans-serif;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: 'Helvetica Neue', Arial, Helvetica, sans-serif;"&gt;For some reason, after seeing code that was blocking for SDL events in a loop, I started building the game with two threads, one blocking for events and one looping and drawing, and a &lt;a href="http://haskell.org/ghc/docs/6.12.2/html/libraries/base-4.2.0.1/Control-Concurrent-MVar.html"&gt;MVar &lt;/a&gt;in the middle. It worked, but rewriting it in a single normal game loop: process event, update game state, draw made things a lot easier.&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: 'Helvetica Neue', Arial, Helvetica, sans-serif;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: 'Helvetica Neue', Arial, Helvetica, sans-serif;"&gt;This brilliant piece of software that has already made its mark in video game history can be found on Hackage &lt;a href="http://hackage.haskell.org/package/TypeClass"&gt;here&lt;/a&gt;!&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: 'Helvetica Neue', Arial, Helvetica, sans-serif;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: 'Helvetica Neue', Arial, Helvetica, sans-serif;"&gt;As usual, all feedback is welcome. Possible enhancements are a high score screen,&amp;nbsp;difficulty&amp;nbsp;levels, choosing letters by&amp;nbsp;frequency&amp;nbsp;in English, using &lt;a href="http://en.wikipedia.org/wiki/Markov_chain#Markov_text_generators"&gt;Markov chains&lt;/a&gt; so that the flow of letters look more natural... The list is infinite!&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/37404288-4049228303107344542?l=jpmoresmau.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jpmoresmau.blogspot.com/feeds/4049228303107344542/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=37404288&amp;postID=4049228303107344542' title='5 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/37404288/posts/default/4049228303107344542'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/37404288/posts/default/4049228303107344542'/><link rel='alternate' type='text/html' href='http://jpmoresmau.blogspot.com/2010/11/simple-game-in-haskell-sdl.html' title='A simple game in Haskell + SDL'/><author><name>JP Moresmau</name><uri>http://www.blogger.com/profile/09964251063221757176</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='26' height='32' src='http://4.bp.blogspot.com/_SFBL69b3jRQ/TIUvCsYa5EI/AAAAAAAAACw/4H33zrk1nAI/S220/shades.jpg'/></author><thr:total>5</thr:total></entry><entry><id>tag:blogger.com,1999:blog-37404288.post-4621974807814282857</id><published>2010-09-30T22:03:00.000+02:00</published><updated>2010-09-30T22:03:54.411+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Eclipse'/><category scheme='http://www.blogger.com/atom/ns#' term='self-publicity'/><category scheme='http://www.blogger.com/atom/ns#' term='Haskell'/><title type='text'>EclipseFP 2.0.0 released!</title><content type='html'>Hello all,&lt;br /&gt;&lt;br /&gt;I'm proud to announce version 2.0.0 of &lt;a href="http://sourceforge.net/projects/eclipsefp/"&gt;EclipseFP&lt;/a&gt;, the Eclipse plugin for Haskell coding. The change in the major version number shows that some big changes have been made, even if under the hood:&lt;br /&gt;- the Antlr parsing has been removed&lt;br /&gt;- the JFace based syntax highlighter has been removed&lt;br /&gt;We now rely solely on Scion and the GHC API to provide lexer tokens! This fixes some long standing syntax highlighting bugs while giving us more options for coloring.&lt;br /&gt;Also, we now communicate to the Scion library via standard streams instead of network calls, which should solve some headaches.&lt;br /&gt;&lt;br /&gt;There are also loads of bug fixes and small enhancements peppered a bit everywhere, either things that people asked or things that I did for myself, since EclipseFP is (of course) my IDE of choice for my Haskell coding. The release notes can be found &lt;a href="https://sourceforge.net/projects/eclipsefp/files/EclipseFP%202%20branch/2.0.0/net.sf.eclipsefp.haskell_2.0.0.txt/download"&gt;here&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;Another good news is that I'm not alone in hacking at EclipseFP, &lt;a href="http://github.com/bscottm"&gt;scooter &lt;/a&gt;has helped a lot with Helios, Cabal 1.6, GHC 6.10 and Mac OS X support, and has a few new features coming up soon!&lt;br /&gt;&lt;br /&gt;Just point your Eclipse to the &lt;a href="http://eclipsefp.sourceforge.net/updates/"&gt;EclipseFP update site&lt;/a&gt;, and happy Haskell hacking!!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/37404288-4621974807814282857?l=jpmoresmau.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jpmoresmau.blogspot.com/feeds/4621974807814282857/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=37404288&amp;postID=4621974807814282857' title='22 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/37404288/posts/default/4621974807814282857'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/37404288/posts/default/4621974807814282857'/><link rel='alternate' type='text/html' href='http://jpmoresmau.blogspot.com/2010/09/eclipsefp-200-released.html' title='EclipseFP 2.0.0 released!'/><author><name>JP Moresmau</name><uri>http://www.blogger.com/profile/09964251063221757176</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='26' height='32' src='http://4.bp.blogspot.com/_SFBL69b3jRQ/TIUvCsYa5EI/AAAAAAAAACw/4H33zrk1nAI/S220/shades.jpg'/></author><thr:total>22</thr:total></entry><entry><id>tag:blogger.com,1999:blog-37404288.post-8713342255573207784</id><published>2010-09-24T14:43:00.001+02:00</published><updated>2010-09-24T14:45:11.794+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='performance'/><category scheme='http://www.blogger.com/atom/ns#' term='Neural Network'/><category scheme='http://www.blogger.com/atom/ns#' term='Artificial Intelligence'/><category scheme='http://www.blogger.com/atom/ns#' term='Haskell'/><title type='text'>Haskell Neural Network: plugging a space leak</title><content type='html'>&lt;span&gt;&lt;br /&gt;First, the good news: last week when I posted about my little digit recognition program I had made a mistake in my test code: when I give a rounded eight to my network, it does recognize it, even though it's been trained only with a square eight! Yoohoo!&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span&gt;&lt;br /&gt;Also, a few people pointed to online database of handwritten digits so that I could get more data to train my network. I dully downloaded and started working with&lt;a href="ftp://ftp.ics.uci.edu/pub/machine-learning-databases/optdigits/"&gt; some files&lt;/a&gt;. Soon I knew I had a problem. Not only was the learning slow, but the memory usage of the program showed exponential growth, like using 400MB after a few iterations. Ha ha, I thought, so it's me against lazy evaluation again! &lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span&gt;&lt;br /&gt;Well, I was right. A couple of strictness annotation in the neuron output calculation function helped performance, nearly making the code twice as fast, but didn't help the memory consumption. Going mad with ! (&lt;a href="http://www.haskell.org/ghc/docs/6.12.2/html/users_guide/bang-patterns.html"&gt;BangPatterns&lt;/a&gt; is your friend) didn't help any more. WTF?&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span&gt;&lt;br /&gt;Then I started to read a bit more about seq and &lt;a href="http://en.wikibooks.org/wiki/Haskell/Graph_reduction#Weak_Head_Normal_Form"&gt;Weak Head Normal Form&lt;/a&gt;. So when I put a BangPattern in front of a tuple, it evaluates the tuple but not what's inside it. And, lo and behold, if at each learning iteration I traced the network to the standard output, memory usage stayed constant! So I needed to tell Haskell to fully evaluate the network each time, so as not to keep thunks full of arithmetic operations hanging round. A distant memory of a package called &lt;a href="http://hackage.haskell.org/package/deepseq"&gt;deepseq&lt;/a&gt; provided me the final help I needed. I didn't use the package itself because I wanted to understand really what's going on, so I just roll out a few lines of my own:&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;script src="http://gist.github.com/595266.js"&gt; &lt;/script&gt;&lt;br /&gt;&lt;span&gt;&lt;br /&gt;And by calling deepSeq on my network in each iteration, my program runs in constant space! And I looked at the flat line of memory usage in my task manager, and I was pleased. Now, I can try to improve the speed of the dang thing, but that's another set of problems...&lt;br /&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/37404288-8713342255573207784?l=jpmoresmau.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jpmoresmau.blogspot.com/feeds/8713342255573207784/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=37404288&amp;postID=8713342255573207784' title='4 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/37404288/posts/default/8713342255573207784'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/37404288/posts/default/8713342255573207784'/><link rel='alternate' type='text/html' href='http://jpmoresmau.blogspot.com/2010/09/haskell-neural-network-plugging-space.html' title='Haskell Neural Network: plugging a space leak'/><author><name>JP Moresmau</name><uri>http://www.blogger.com/profile/09964251063221757176</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='26' height='32' src='http://4.bp.blogspot.com/_SFBL69b3jRQ/TIUvCsYa5EI/AAAAAAAAACw/4H33zrk1nAI/S220/shades.jpg'/></author><thr:total>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-37404288.post-6816623105547524829</id><published>2010-09-17T17:17:00.000+02:00</published><updated>2010-09-17T17:17:05.984+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Neural Network'/><category scheme='http://www.blogger.com/atom/ns#' term='Artificial Intelligence'/><category scheme='http://www.blogger.com/atom/ns#' term='Haskell'/><title type='text'>Digit recognition with a neural network. First attempt!</title><content type='html'>&lt;span class="Apple-style-span" style="font-family: inherit;"&gt;I bought myself "&lt;/span&gt;&lt;a href="http://www.onintelligence.org/"&gt;&lt;span class="Apple-style-span" style="font-family: inherit;"&gt;On Intelligence&lt;/span&gt;&lt;/a&gt;&lt;span class="Apple-style-span" style="font-family: inherit;"&gt;", and I thought as the first step on the long road to building an intelligent machine I would go back to neural networks. I have my own little library that seems to work (&lt;/span&gt;&lt;a href="http://jpmoresmau.blogspot.com/2010/04/found-my-neural-network-bug-three-years.html"&gt;&lt;span class="Apple-style-span" style="font-family: inherit;"&gt;kind of&lt;/span&gt;&lt;/a&gt;&lt;span class="Apple-style-span" style="font-family: inherit;"&gt;), so I decided I was going to try to write a little number recognition program. I was inspired of course by &lt;/span&gt;&lt;a href="http://www.ai-junkie.com/ann/evolved/nnt4.html"&gt;&lt;span class="Apple-style-span" style="font-family: inherit;"&gt;ai-junkie&lt;/span&gt;&lt;/a&gt;&lt;span class="Apple-style-span" style="font-family: inherit;"&gt;, but it was a bit short on details...&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: inherit;"&gt;So here is the problem: I have a 5x5 grid of LEDs that can be on or off, and I want to recognize the digit that they show.&amp;nbsp;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: inherit;"&gt;The input will be a list of 25 numbers, either 0 (off) or 1 (on)&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: inherit;"&gt;The output will be a list of 10 numbers, either 0 or 1. The first position of a 1 indicates the result (so if the first element is a 1, it's number 0, etc).&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: inherit;"&gt;I arbitrarily decide to set the number of hidden neurons to 50, twice the input neurons. So my topology is 25-50-10.&amp;nbsp;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: inherit;"&gt;I train the network with only one version of each digit. For example 3 would be:&lt;/span&gt;&lt;br /&gt;&lt;pre&gt;*****&lt;br /&gt;    *&lt;br /&gt; ****&lt;br /&gt;    *&lt;br /&gt;*****&lt;/pre&gt;&lt;span class="Apple-style-span" style="font-family: inherit;"&gt;Wrote a few lines of Haskell code to read the training sets (moving from the representation with *, spaces and new lines to the list of 1 and 0, so that 3 becomes: [1.0,1.0,1.0,1.0,1.0,0.0,0.0,0.0,0.0,1.0,0.0,1.0,1.0,1.0,1.0,0.0,0.0,0.0,0.0,1.0,1.0,1.0,1.0,1.0,1.0]).&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: inherit;"&gt;Then I train the network. It learns after 200 iterations, and successfully recognizes the training sets (ok, so things are working as they should be).&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: inherit;"&gt;Then the real test: can my network recognize small variants of the training set?&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: inherit;"&gt;Lets's try with:&lt;/span&gt;&lt;br /&gt;&lt;pre&gt;****&lt;br /&gt;    *&lt;br /&gt; ***&lt;br /&gt;    *&lt;br /&gt;****&lt;/pre&gt;&lt;span class="Apple-style-span" style="font-family: inherit;"&gt;(a slightly rounded 3): the network answers 3!!&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: inherit;"&gt;Works also for a slightly rounded 6. But then:&lt;/span&gt;&lt;br /&gt;&lt;pre&gt; ***&lt;br /&gt;*   *&lt;br /&gt; ***&lt;br /&gt;*   *&lt;br /&gt; ***&lt;/pre&gt;&lt;span class="Apple-style-span" style="font-family: inherit;"&gt;(rounded 8) gives me 6. Oh dear... I could probably add more cases in the training sets and hopefully resolve the ambiguities, but there are bigger issues (I know I know, I'm very candid, but it's one thing being told something in a book, and another to build something to actually show it to you). For example:&lt;/span&gt;&lt;br /&gt;&lt;pre&gt;***&lt;br /&gt;* *&lt;br /&gt;***&lt;/pre&gt;&lt;span class="Apple-style-span" style="font-family: inherit;"&gt;Is a small zero that doesn't take the full 5 LED width. My network recognizes 0 when it fills the full square, not when it's smaller (tells me it's a 5).&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: inherit;"&gt;And of course, 1 is a disaster. The training "1" is a vertical row of LEDs on the left. A vertical row of LEDs on the right gives me 9, usually (and I suppose, 9 has all the LEDs on the right on).&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: inherit;"&gt;So not only is basic training not sufficient to detect simple variations, but also the fact that we deal with absolute positioning of leds mean than scaling and simple side translations are not supported. So I suppose the next step is to not work with absolute positions, but relative positions of "on" LEDs. Another day's work...&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/37404288-6816623105547524829?l=jpmoresmau.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jpmoresmau.blogspot.com/feeds/6816623105547524829/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=37404288&amp;postID=6816623105547524829' title='6 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/37404288/posts/default/6816623105547524829'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/37404288/posts/default/6816623105547524829'/><link rel='alternate' type='text/html' href='http://jpmoresmau.blogspot.com/2010/09/digit-recognition-with-neural-network.html' title='Digit recognition with a neural network. First attempt!'/><author><name>JP Moresmau</name><uri>http://www.blogger.com/profile/09964251063221757176</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='26' height='32' src='http://4.bp.blogspot.com/_SFBL69b3jRQ/TIUvCsYa5EI/AAAAAAAAACw/4H33zrk1nAI/S220/shades.jpg'/></author><thr:total>6</thr:total></entry><entry><id>tag:blogger.com,1999:blog-37404288.post-1523026304842611132</id><published>2010-09-06T20:04:00.000+02:00</published><updated>2010-09-06T20:04:10.520+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='performance'/><category scheme='http://www.blogger.com/atom/ns#' term='Eclipse'/><category scheme='http://www.blogger.com/atom/ns#' term='parsing'/><category scheme='http://www.blogger.com/atom/ns#' term='Haskell'/><title type='text'>EclipseFP development: using the GHC Lexer</title><content type='html'>&lt;span class="Apple-style-span" style="font-family: Verdana, sans-serif;"&gt;The new version of EclipseFP is slowly coming along. Slowly, because of some holidays, because of a lot of bug fixes, and mainly because of some big changes.&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: Verdana, sans-serif;"&gt;There were a few bugs revolving around syntax highlighting. The original code was using some lexing rules from the JFace packages in Eclipse, but it didn't cover some common enough cases of Haskell syntax, and of course was fairly hopeless at more complex stuff (things like Template Haskell). So I could either trod on and fix the lexing rules for everything, or I could use a different approach. So I decided to use Scion again, and to add support for lexing. Now Scion exposes a method that calls the &lt;a href="http://www.haskell.org/ghc/docs/6.12.2/html/libraries/ghc-6.12.2/Lexer.html"&gt;GHC Lexer&lt;/a&gt; on an arbitrary Haskell source. We use the result to color highlight properly the Haskell source code. Of course I have to handle things like CPP preprocessing directives and literal source files myself, but that was ok. The two main issues I had to tackle were performance, and advanced lexing options.&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: Verdana, sans-serif;"&gt;Performance was poor at start, and there are two reasons: the underlying Scion code deals with JSON Strings while the socket code uses ByteStrings, and, I think, the Eclipse console. For the first issue, I'm using now &lt;a href="http://hackage.haskell.org/package/AttoJson"&gt;AttoJson&lt;/a&gt;, so that Json marshalling is done with ByteStrings and try to use ByteString as much as possible in the code. The Eclipse console is a different matter. I think when too much data is written to it it struggles to update the console control, blocks the UI thread and the whole UI becomes unresponsive. For the moment, I have disabled server output in the console for commands (since now getting the tokens from the source code is quite a big response). Since lexing is also done in the UI thread, we've probably lost a bit in that area, but I feel the advantages (less Haskell knowledge in the Java code, more reliance on the GHC code, which I suspect knows about Haskell pretty well) outweigh the costs.&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: Verdana, sans-serif;"&gt;One funny thing with the Lexer I found: for example when you have TemplateHaskell code in your source file, and you have the TemplateHaskell pragma, the Lexer doesn't automatically set the TemplateHaskell flag. So I decided that I was going to enable &lt;a href="http://www.haskell.org/ghc/docs/6.12.2/html/libraries/ghc-6.12.2/src/Lexer.html#mkPState"&gt;all the lexer flags&lt;/a&gt;, since performance didn't seem to suffer. Be liberal in what you parse...&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: Verdana, sans-serif;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: Verdana, sans-serif;"&gt;Anyway, I'm not going to release the next version right now, a bit of testing is still needed, and there are a few little things that I want to fix. The testing is easy, in a way: I use the development version of EclipseFP to hack the Scion code, so by eating my own dog food I hope that I can release something of value to Haskell programmers.&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: Verdana, sans-serif;"&gt;So don't worry, EclipseFP is coming soon!&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/37404288-1523026304842611132?l=jpmoresmau.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jpmoresmau.blogspot.com/feeds/1523026304842611132/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=37404288&amp;postID=1523026304842611132' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/37404288/posts/default/1523026304842611132'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/37404288/posts/default/1523026304842611132'/><link rel='alternate' type='text/html' href='http://jpmoresmau.blogspot.com/2010/09/eclipsefp-development-using-ghc-lexer.html' title='EclipseFP development: using the GHC Lexer'/><author><name>JP Moresmau</name><uri>http://www.blogger.com/profile/09964251063221757176</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='26' height='32' src='http://4.bp.blogspot.com/_SFBL69b3jRQ/TIUvCsYa5EI/AAAAAAAAACw/4H33zrk1nAI/S220/shades.jpg'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-37404288.post-5532463649330559560</id><published>2010-06-02T15:59:00.000+02:00</published><updated>2010-06-02T15:59:28.462+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Eclipse'/><category scheme='http://www.blogger.com/atom/ns#' term='self-publicity'/><category scheme='http://www.blogger.com/atom/ns#' term='Haskell'/><title type='text'>EclipseFP 1.111 released</title><content type='html'>&lt;span class="Apple-style-span" style="font-family: Arial, Helvetica, sans-serif;"&gt;I have just released version 1.111 of EclipseFP. You can get it from &lt;/span&gt;&lt;a href="https://sourceforge.net/projects/eclipsefp/"&gt;&lt;span class="Apple-style-span" style="font-family: Arial, Helvetica, sans-serif;"&gt;sourceforge&lt;/span&gt;&lt;/a&gt;&lt;span class="Apple-style-span" style="font-family: Arial, Helvetica, sans-serif;"&gt; or via the Eclipse update site (&lt;/span&gt;&lt;a href="http://eclipsefp.sourceforge.net/updates/"&gt;&lt;span class="Apple-style-span" style="font-family: Arial, Helvetica, sans-serif;"&gt;http://eclipsefp.sourceforge.net/updates/&lt;/span&gt;&lt;/a&gt;&lt;span class="Apple-style-span" style="font-family: Arial, Helvetica, sans-serif;"&gt;).&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: Arial, Helvetica, sans-serif;"&gt;This is mostly a bug-fixing release to ensure compatibility with GHC 6.12.1 (Haskell Platform 2010) and IPv6. It also bundles a version of the Scion source code that it builds under the covers to save people from downloading the source code from github and building it themselves.&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: Arial, Helvetica, sans-serif;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: Arial, Helvetica, sans-serif;"&gt;There aren't too many feature enhancements because I didn't get any requests for it. I'm not too sure a lot of people are using EclipseFP and are interested in seeing it improved. I suppose now with a Cabalized gtk2hs Leksah becomes more attractive. Anyway, if you have requests for EclipseFP let me know!&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: Arial, Helvetica, sans-serif;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/37404288-5532463649330559560?l=jpmoresmau.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jpmoresmau.blogspot.com/feeds/5532463649330559560/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=37404288&amp;postID=5532463649330559560' title='29 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/37404288/posts/default/5532463649330559560'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/37404288/posts/default/5532463649330559560'/><link rel='alternate' type='text/html' href='http://jpmoresmau.blogspot.com/2010/06/eclipsefp-1111-released.html' title='EclipseFP 1.111 released'/><author><name>JP Moresmau</name><uri>http://www.blogger.com/profile/09964251063221757176</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='26' height='32' src='http://4.bp.blogspot.com/_SFBL69b3jRQ/TIUvCsYa5EI/AAAAAAAAACw/4H33zrk1nAI/S220/shades.jpg'/></author><thr:total>29</thr:total></entry><entry><id>tag:blogger.com,1999:blog-37404288.post-178880597336276584</id><published>2010-05-28T16:12:00.000+02:00</published><updated>2010-05-28T16:12:44.353+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='GUI'/><category scheme='http://www.blogger.com/atom/ns#' term='Haskell'/><title type='text'>Gtk2hs and Leksah on Windows, check!</title><content type='html'>&lt;span class="Apple-style-span" style="font-family: Arial, Helvetica, sans-serif;"&gt;Things have moved since I&lt;a href="http://jpmoresmau.blogspot.com/2010/04/sorry-plight-of-windows-programmer-aka.html"&gt; posted&lt;/a&gt; about the difficulty of being a Haskell programmer on Windows. Now, Gtk2hs has been&lt;a href="http://haskell.org/gtk2hs/archives/2010/05/25/gtk2hs-0110-released/"&gt; cabalized and put on Hackage&lt;/a&gt;. I went into my MSYS prompt, and it installed like a charm! I've downloaded the latest version of &lt;a href="http://leksah.org/"&gt;Leksah&lt;/a&gt;, and it installed and started properly! As I write this I've seen the initial Leksah screen, and it's now busy referencing my packages (I wonder if giving it the location where Cabal stores the packages it downloads was a good idea, it seem to be taking a while...).&amp;nbsp;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: Arial, Helvetica, sans-serif;"&gt;So I think now all the things I was struggling to get working are now installed and doing fine on my Windows 7 machine! There is hope!&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/37404288-178880597336276584?l=jpmoresmau.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jpmoresmau.blogspot.com/feeds/178880597336276584/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=37404288&amp;postID=178880597336276584' title='4 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/37404288/posts/default/178880597336276584'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/37404288/posts/default/178880597336276584'/><link rel='alternate' type='text/html' href='http://jpmoresmau.blogspot.com/2010/05/gtk2hs-and-leksah-on-windows-check.html' title='Gtk2hs and Leksah on Windows, check!'/><author><name>JP Moresmau</name><uri>http://www.blogger.com/profile/09964251063221757176</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='26' height='32' src='http://4.bp.blogspot.com/_SFBL69b3jRQ/TIUvCsYa5EI/AAAAAAAAACw/4H33zrk1nAI/S220/shades.jpg'/></author><thr:total>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-37404288.post-6368038058575449232</id><published>2010-05-05T16:48:00.003+02:00</published><updated>2010-05-05T17:12:38.195+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='games'/><category scheme='http://www.blogger.com/atom/ns#' term='GUI'/><category scheme='http://www.blogger.com/atom/ns#' term='Haskell'/><title type='text'>Haskell SDL on Windows, check! (hacking required)</title><content type='html'>Things looked grim. Even though &lt;a href="http://web.animal-machine.com:8080/blog/2010/04/a-haskell-adventure-in-windows/"&gt;Timothy could get it to work&lt;/a&gt;, the SDL Haskell library wouldn't build for me. libSDL itself installed ok and the samples compiled and ran. But I couldn't compile the hsc files because of a linker error: gcc couldn't find SDLMain or whatever. In desperation, I posted to &lt;a href="http://www.mail-archive.com/haskell-cafe@haskell.org/msg74841.html"&gt;Haskell-cafe&lt;/a&gt;. I didn't get a single answer or hint. I was truly alone.&lt;br /&gt;&lt;div&gt;OK, it was time to either give up or take drastic action. And I never give up.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;By then I had narrowed the problem. The order of arguments to gcc were wrong for linking, according to the &lt;a href="http://gcc.gnu.org/onlinedocs/gcc/Link-Options.html"&gt;gcc manual&lt;/a&gt;: the .o file should be referenced before the SDL libraries on the command line. It would work like that for other people, but for me, on my system, in my corner of the universe, the order was wrong, and that was it. If I tried the same order of arguments on the SDL samples, they would fail to link. If I reverted the arguments, they would succeed.&lt;/div&gt;&lt;div&gt;So I was left with the straight and narrow: I managed to get the source code for &lt;a href="http://darcs.haskell.org/hsc2hs"&gt;hsc2hs from darcs&lt;/a&gt;. I fiddled for a while with the include-dirs and extra-lib options so I could get it to compile and produce the same error than I had with the Haskell Platform version, and not some stupid errors about hsFFI.h not found or so.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Then I opened up, hands trembling and sweat pouring from my forehead, Main.hs in an editor. Found the offending lines:&lt;/div&gt;&lt;div&gt;&lt;blockquote&gt;&lt;pre&gt;    rawSystemL ("linking " ++ oProgName) beVerbose linker&lt;br /&gt;       (  [f | LinkFlag f &lt;- flags]         &lt;br /&gt;       ++ [oProgName]&lt;br /&gt;       ++ ["-o", progName]&lt;br /&gt;       )&lt;/pre&gt;&lt;/blockquote&gt;&lt;/div&gt;&lt;br /&gt;&lt;div&gt;Changed them to:&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;blockquote&gt;&lt;pre&gt;      rawSystemL ("linking " ++ oProgName) beVerbose linker&lt;br /&gt;       ( [oProgName]&lt;br /&gt;       ++  [f | LinkFlag f &lt;- flags]&lt;br /&gt;       ++ ["-o", progName]  &lt;br /&gt;)&lt;/pre&gt;&lt;/blockquote&gt;&lt;/div&gt;&lt;div&gt;So that the name of the o file would be before the libraries.&lt;/div&gt;&lt;div&gt;Recompiled, copied the exe in the Haskell Platform bin folder...&lt;/div&gt;&lt;div&gt;Relaunched the SDL build...&lt;/div&gt;&lt;div&gt;And watched SDL build and install properly! &lt;/div&gt;&lt;div&gt;Gaped at the &lt;a href="http://web.animal-machine.com:8080/blog/2010/04/getting-started-with-sdl-in-haskell/"&gt;first sample of Timothy&lt;/a&gt; opening up a blank window that would close when I press a key! (OK, the last print fails, but by now little errors are not going to disturb my feeling of invulnerability).&lt;/div&gt;&lt;div&gt;Danced around my desk!&lt;/div&gt;&lt;div&gt;Had a beer!&lt;br /&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/37404288-6368038058575449232?l=jpmoresmau.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jpmoresmau.blogspot.com/feeds/6368038058575449232/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=37404288&amp;postID=6368038058575449232' title='10 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/37404288/posts/default/6368038058575449232'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/37404288/posts/default/6368038058575449232'/><link rel='alternate' type='text/html' href='http://jpmoresmau.blogspot.com/2010/05/haskell-sdl-on-windows-check-hacking.html' title='Haskell SDL on Windows, check! (hacking required)'/><author><name>JP Moresmau</name><uri>http://www.blogger.com/profile/09964251063221757176</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='26' height='32' src='http://4.bp.blogspot.com/_SFBL69b3jRQ/TIUvCsYa5EI/AAAAAAAAACw/4H33zrk1nAI/S220/shades.jpg'/></author><thr:total>10</thr:total></entry><entry><id>tag:blogger.com,1999:blog-37404288.post-308213152841159413</id><published>2010-04-30T14:53:00.005+02:00</published><updated>2010-04-30T15:10:19.496+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Haskell'/><title type='text'>Happstack on Window, check! (in a long, round-about, fear-inducing way)</title><content type='html'>&lt;div style="text-align: justify;"&gt;&lt;a href="http://jpmoresmau.blogspot.com/2010/04/sorry-plight-of-windows-programmer-aka.html"&gt;The other day&lt;/a&gt; I noted that I couldn't install the darcs version of &lt;a href="http://happstack.com/index.html"&gt;Happstack&lt;/a&gt; on my windows machine. There was a build failure that was reported on the mailing list. So I waited a few days, and tried again. But then, before I started building Happstack, something happened. I don't exactly remember what, I think I was a bit to eager with &lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;cabal upgrade&lt;/span&gt;, and I upgraded some base packages that I shouldn't have. I remember &lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;directory-1.0.1.1&lt;/span&gt; failing to build and having to go through MSYS to get it to build. Then more and more things needed to be upgraded and &lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;ghc-pkg check&lt;/span&gt; was reporting more and more weird things. When I thought I had upgraded everything, I tried happstack. &lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;happstack-util&lt;/span&gt; built, but then &lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;happstack-data&lt;/span&gt; reported that &lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;happstack-util&lt;/span&gt; couldn't be built because it required both &lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;time-1.1.4&lt;/span&gt; and &lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;time-2-something&lt;/span&gt;. Oh oh. I screwed around for a while. Then I saw some posts on the web talking about removing &lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;package.conf.d&lt;/span&gt;. In my random experiments with cabal upgrade I had managed to install everything in my user profile and not inside my Haskell Platform directory, so there was hope!&lt;/div&gt;&lt;div style="text-align: justify;"&gt;I deleted &lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;package.conf.d&lt;/span&gt;. &lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;ghc-pkg list&lt;/span&gt; reported a saner list of packages. I tried building happstack again. Then something "funny" happened: every cabal build I was trying to do first tried to reinstall &lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;process-1.0.1.2&lt;/span&gt;, and failed every time!! And of course &lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;process-1.0.1.2&lt;/span&gt; appeared in the ouput of &lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;ghc-pkg list&lt;/span&gt;... WTF? Ah, ok, &lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;directory-1.0.1.1&lt;/span&gt; is still installed, let's kill the beast! And then everything worked! Happstack built, happstack "hello world" server even runs, life is happy again! &lt;/div&gt;&lt;div style="text-align: justify;"&gt;I didn't try to investigate why Cabal or &lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;directory-1.0.1.1 &lt;/span&gt;were insisting on reinstalling something that I have already. I've seen enough weird things and spent enough time this week away from the nice world of pure lazy functional programming and in dirty low-level configuration and build issues to not care too much anymore...&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/37404288-308213152841159413?l=jpmoresmau.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jpmoresmau.blogspot.com/feeds/308213152841159413/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=37404288&amp;postID=308213152841159413' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/37404288/posts/default/308213152841159413'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/37404288/posts/default/308213152841159413'/><link rel='alternate' type='text/html' href='http://jpmoresmau.blogspot.com/2010/04/happstack-on-window-check-in-long-round.html' title='Happstack on Window, check! (in a long, round-about, fear-inducing way)'/><author><name>JP Moresmau</name><uri>http://www.blogger.com/profile/09964251063221757176</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='26' height='32' src='http://4.bp.blogspot.com/_SFBL69b3jRQ/TIUvCsYa5EI/AAAAAAAAACw/4H33zrk1nAI/S220/shades.jpg'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-37404288.post-5035839310107930917</id><published>2010-04-28T20:48:00.004+02:00</published><updated>2010-04-28T21:01:34.211+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='GUI'/><category scheme='http://www.blogger.com/atom/ns#' term='Haskell'/><title type='text'>WXWidgets and WxHaskell on Windows, check!</title><content type='html'>Despite my &lt;a href="http://jpmoresmau.blogspot.com/2010/04/sorry-plight-of-windows-programmer-aka.html"&gt;earlier problems&lt;/a&gt;, I finally managed to install WXWidgets and WxHaskell on my Windows machine. Pfiu! I started again from scratch, and things went much better when I installed, as recommended, MinGW and MSYS in different folders. When I need to compile stuff, I only put MinGW in my path, and when I need Unixy tools like make I add MSYS. Of course MinGW has its own version of make, mingw32-make, that works when MSYS make doesn't...&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;So I installed MinGW in c:\dev\MinGW and:&lt;/div&gt;&lt;div&gt;&lt;pre&gt;set PATH=c:\dev\MinGW\bin;c:\dev\MinGW\libexec\gcc\mingw32\3.4.5;%PATH%&lt;/pre&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Then I modified the WxWidgets config.gcc file to set SHARED=1 UNICODE=1 MONOLITHIC=1.&lt;/div&gt;&lt;div&gt;And then:&lt;/div&gt;&lt;div&gt;&lt;pre&gt;mingw32-make -f makefile.gcc BUILD=debug&lt;/pre&gt;&lt;/div&gt;&lt;div&gt;worked!&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Setting new environment variables (wxWidgets is installed in c:\ui):&lt;/div&gt;&lt;div&gt;&lt;pre&gt;set WXWIN=c:\ui\wxWidgets-2.8.10&lt;br /&gt;set WXCFG=gcc_dll\mswud&lt;/pre&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Then I could install then wxdirect, wxcore and wx packages using a few more flags than what a default cabal install would do, for example:&lt;/div&gt;&lt;div&gt;&lt;pre&gt;runhaskell Setup configure --extra-lib-dirs=c:\dev\MinGW\lib --extra-include-dirs=c:\dev\MinGW\include --extra-include-dirs=c:\dev\MinGW\include\c++\3.4.5\mingw32 --extra-include-dirs=c:\ui\wxWidgets-2.8.10\include --extra-include-dirs=c:\dev\MinGW\include\c++\3.4.5&lt;/pre&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;And it install, and works!&lt;/div&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/37404288-5035839310107930917?l=jpmoresmau.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jpmoresmau.blogspot.com/feeds/5035839310107930917/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=37404288&amp;postID=5035839310107930917' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/37404288/posts/default/5035839310107930917'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/37404288/posts/default/5035839310107930917'/><link rel='alternate' type='text/html' href='http://jpmoresmau.blogspot.com/2010/04/wxwidgets-and-wxhaskell-on-windows.html' title='WXWidgets and WxHaskell on Windows, check!'/><author><name>JP Moresmau</name><uri>http://www.blogger.com/profile/09964251063221757176</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='26' height='32' src='http://4.bp.blogspot.com/_SFBL69b3jRQ/TIUvCsYa5EI/AAAAAAAAACw/4H33zrk1nAI/S220/shades.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-37404288.post-3388609978156961041</id><published>2010-04-22T17:03:00.003+02:00</published><updated>2010-04-22T17:35:06.206+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='GUI'/><category scheme='http://www.blogger.com/atom/ns#' term='Haskell'/><title type='text'>The sorry plight of a Windows programmer (aka me)</title><content type='html'>&lt;div style="text-align: justify;"&gt;Having secured fame and fortune with &lt;a href="http://hackage.haskell.org/package/MazesOfMonad"&gt;MazesOfMonad&lt;/a&gt;, my console based RPG, and having some ideas for some games that would look even better with a graphical front end, I decided it was time to take the bulls by the horn and go seriously into Haskell GUI programming. Well, the bull won and I feel truly gored...&lt;/div&gt;&lt;div style="text-align: justify;"&gt;So what's wrong? Well, after fooling around on my Windows 7 computer for a few nights I've achieved nothing. I now have three different copies of &lt;a href="http://www.mingw.org/"&gt;MinGW&lt;/a&gt; installed in different places. I have tried to installed &lt;a href="http://hackage.haskell.org/package/SDL"&gt;SDL&lt;/a&gt;, &lt;a href="http://www.haskell.org/gtk2hs/"&gt;GTK2HS&lt;/a&gt;, &lt;a href="http://www.wxwidgets.org/"&gt;WXWidgets&lt;/a&gt; and &lt;a href="http://happstack.com/index.html"&gt;Happstack&lt;/a&gt; and I have failed at all of them. I know WXWidgets is manageable because I've done it before, I only seem to have some include paths issues. libSDL itself installed but not the Haskell bindings. I found somebody with &lt;a href="http://www.mail-archive.com/haskell-cafe@haskell.org/msg65756.html"&gt;the same problem&lt;/a&gt; on the web, that then told me he had given up. I even managed to get Darcs errors with &lt;a href="http://haskell.org/gtk2hs/archives/2010/04/21/cabalized-version-of-gtk2hs-now-up-for-testing/"&gt;Gtk2Hs&lt;/a&gt;. In despair I thought I could develop a web based game but even the darcs version of happstack failed to compile, I remembered then &lt;a href="http://groups.google.com/group/happs/browse_thread/thread/4e2cb73b3c312ebe"&gt;some bug&lt;/a&gt; mentioned on the mailing list, so I should probably just download the latest stable version instead of the development branch.&lt;/div&gt;&lt;div style="text-align: justify;"&gt;Some problems are down to some silly things I did. For example installing the Haskell Platform in a directory with spaces is not a great idea (I don't remember if it was the default), because then a lot of paths referencing its MinGW install are wrong in the MSYS shell...&lt;/div&gt;&lt;div style="text-align: justify;"&gt;But most are due to the Unixy nature of a lot of the GUI components. Now I see a configure script and my blood freezes. I run "cabal install foo" and I get the dreaded message "this package has a configure script, you need to dive into Unix hell". Can you tell me why I have three versions of GCC, and two make a configure script crash with "c compiler cannot create executables" and the third one works? Where can I download one single file that will allow me to have a full MSYS/MinGW setup with most of what I need? I'm sure there are solutions to a lot of the problems I have, and maybe I need to spend more time reading the INSTALL files and such, and download everything from the &lt;a href="https://sourceforge.net/projects/mingw/files/"&gt;MinGW files page&lt;/a&gt;. But why can't it Just Work? I mean, I work with Java at work, we do GUI work in SWT now and before that in Swing, we use a lot of libraries, and we never run into any installation problem. Maybe once or twice over the past couple of years we had a cross-platform compatibility issue or a library conflict. I know, I know, apples and oranges, but I'm now thinking that writing my own lazy, purely functional language with monads on top of the JVM with Java integration is going to be easier than getting a GUI library with Haskell bindings to work. &lt;/div&gt;&lt;div style="text-align: justify;"&gt;I like to write applications, not spend my free time trying to get libraries to install.&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/37404288-3388609978156961041?l=jpmoresmau.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jpmoresmau.blogspot.com/feeds/3388609978156961041/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=37404288&amp;postID=3388609978156961041' title='13 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/37404288/posts/default/3388609978156961041'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/37404288/posts/default/3388609978156961041'/><link rel='alternate' type='text/html' href='http://jpmoresmau.blogspot.com/2010/04/sorry-plight-of-windows-programmer-aka.html' title='The sorry plight of a Windows programmer (aka me)'/><author><name>JP Moresmau</name><uri>http://www.blogger.com/profile/09964251063221757176</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='26' height='32' src='http://4.bp.blogspot.com/_SFBL69b3jRQ/TIUvCsYa5EI/AAAAAAAAACw/4H33zrk1nAI/S220/shades.jpg'/></author><thr:total>13</thr:total></entry><entry><id>tag:blogger.com,1999:blog-37404288.post-11625496560538297</id><published>2010-04-09T17:26:00.004+02:00</published><updated>2010-04-09T17:39:12.080+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Neural Network'/><category scheme='http://www.blogger.com/atom/ns#' term='Artificial Intelligence'/><category scheme='http://www.blogger.com/atom/ns#' term='Haskell'/><title type='text'>Found my neural  network bug (three years later)</title><content type='html'>&lt;div style="text-align: justify;"&gt;&lt;span class="Apple-style-span"  style="font-family:arial;"&gt;After the university of &lt;/span&gt;&lt;a href="http://csclub.uwaterloo.ca/contest/"&gt;&lt;span class="Apple-style-span"  style="font-family:arial;"&gt;Waterloo  AI Challenge&lt;/span&gt;&lt;/a&gt;&lt;span class="Apple-style-span"  style="font-family:arial;"&gt; I went back to a bit of AI programming in Haskell. &lt;/span&gt;&lt;a href="http://jpmoresmau.blogspot.com/2007/06/very-dumb-neural-network-in-haskell.html"&gt;&lt;span class="Apple-style-span"  style="font-family:arial;"&gt;Three  years ago&lt;/span&gt;&lt;/a&gt;&lt;span class="Apple-style-span"  style="font-family:arial;"&gt; I had written some code to implement a neural network,  and it didn't seem to learn as fast as the book said it should. I had  not worked on that any more, but I decided to look at it again. And I  found a bug!! I mixed up the deltas to pass on from one run to the next.  Changing two lines of code makes my network learning much faster.&lt;/span&gt;&lt;/div&gt;&lt;span class="Apple-style-span"  style="font-family:arial;"&gt;&lt;div style="text-align: justify;"&gt;So now onto something a bit more meaty than exclusive or: very simple  character recognition. I want to be able to recognize numbers written as  a digital alarm clock would display them (at least mine): you have 7  lights, four vertical and three horizontal, and various patterns make  the numbers. If all lights are on, it's 8, if only the middle horizontal  light is off we have zero, etc...&lt;/div&gt;&lt;/span&gt;&lt;div style="text-align: justify;"&gt;&lt;span class="Apple-style-span"  style="font-family:arial;"&gt;I just test things with a network that has 7 input neurons (one for each  light), 10 output neurons (one for each number) and 8 hidden neurons  (the average between input and output)&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:arial;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;g&lt;-getStdGen&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;n&lt;-network 7 8 10&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;let trainingSet=[&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;                ([1,1,1,-1,1,1,1],[1,0,0,0,0,0,0,0,0,0]), -- 0&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;                ([-1,-1,1,-1,-1,1,-1],[0,1,0,0,0,0,0,0,0,0]), -- 1&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;                ([1,-1,1,1,1,-1,1],[0,0,1,0,0,0,0,0,0,0]), -- 2&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;                ([1,-1,1,1,-1,1,1],[0,0,0,1,0,0,0,0,0,0]), -- 3&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;                ([-1,1,1,1,-1,1,-1],[0,0,0,0,1,0,0,0,0,0]), -- 4&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;                ([1,1,-1,1,-1,1,1],[0,0,0,0,0,1,0,0,0,0]), -- 5&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;                ([1,1,-1,1,1,1,1],[0,0,0,0,0,0,1,0,0,0]), -- 6 &lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;                ([1,1,1,-1,-1,1,-1],[0,0,0,0,0,0,0,1,0,0]), -- 7&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;                ([1,1,1,1,1,1,1],[0,0,0,0,0,0,0,0,1,0]), -- 8&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;                ([1,1,1,1,-1,1,1],[0,0,0,0,0,0,0,0,0,1]) -- 9&lt;/span&gt;&lt;/div&gt;&lt;div&gt;                &lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;                ]&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt; let (LNS(n',err,ds),e) = run (initialState n) defaultLearningRate trainingSet (1,1000)&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:arial;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;span class="Apple-style-span"  style="font-family:arial;"&gt;And after something like 150 iterations I get a network that has a low error rate. A little helper method to massage the results:&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:arial;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;runNumber n inputs=do&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;        let &lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;                (_, output)=exec n inputs&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;                normalized=map (\v-&gt;if (1-v)&gt;0.5 then 0 else 1) output&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;        return $ elemIndex 1 normalized   &lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:arial;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:arial;"&gt;Et voila!&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:arial;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;Main&gt; runNumber nn [1,-1,1,1,-1,1,1]&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;Just 3&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:arial;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;span class="Apple-style-span"  style="font-family:arial;"&gt;Now, things are starting to get interesting! Hopefully I won't wait another three years before trying maybe more complex character recognition.&lt;/span&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/37404288-11625496560538297?l=jpmoresmau.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jpmoresmau.blogspot.com/feeds/11625496560538297/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=37404288&amp;postID=11625496560538297' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/37404288/posts/default/11625496560538297'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/37404288/posts/default/11625496560538297'/><link rel='alternate' type='text/html' href='http://jpmoresmau.blogspot.com/2010/04/found-my-neural-network-bug-three-years.html' title='Found my neural  network bug (three years later)'/><author><name>JP Moresmau</name><uri>http://www.blogger.com/profile/09964251063221757176</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='26' height='32' src='http://4.bp.blogspot.com/_SFBL69b3jRQ/TIUvCsYa5EI/AAAAAAAAACw/4H33zrk1nAI/S220/shades.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-37404288.post-139312455087173365</id><published>2010-02-11T13:20:00.006+01:00</published><updated>2010-02-11T13:50:59.139+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='games'/><category scheme='http://www.blogger.com/atom/ns#' term='Artificial Intelligence'/><category scheme='http://www.blogger.com/atom/ns#' term='Haskell'/><title type='text'>Waterloo Contest and Human Intelligence</title><content type='html'>I've entered the Waterloo university &lt;a href="http://csclub.uwaterloo.ca/contest"&gt;Google AI Challenge&lt;/a&gt;, hiding under a cunning nickname, since I saw that you could develop in Haskell, and a &lt;a href="http://www.reddit.com/r/haskell/comments/ay5sc/google_ai_challenge_finishes_february_26_you_can/"&gt;few others Haskellers&lt;/a&gt; are on it too! At the moment, I'm cruising at around the 110th position, which is not too bad given that I only worked a few hours at night on it (I have a day job, you know...) and that I implemented everything myself since the starter pack wasn't ready when I started working. I've played a bit with the standard strategies, implemented some &lt;a href="http://en.wikipedia.org/wiki/Floodfill"&gt;flood fill&lt;/a&gt;, reuse some &lt;a href="http://en.wikipedia.org/wiki/A*_search_algorithm"&gt;A*&lt;/a&gt; implementation I have.&lt;br /&gt;All of this is interesting, of course, but there is no AI as such. The only intelligence in my code is the one I put in, and the strategies I devised. So I'm thinking of playing around with genetic programming and evolution techniques to try to get my code to find the right strategies at the right time. I have the feeling the trick will be to design something that is not too restricted and is truly able to evolve into some more advanced and complex than what I've designed myself. But hey, I'll learn, even if my program doesn't (-:&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/37404288-139312455087173365?l=jpmoresmau.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jpmoresmau.blogspot.com/feeds/139312455087173365/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=37404288&amp;postID=139312455087173365' title='4 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/37404288/posts/default/139312455087173365'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/37404288/posts/default/139312455087173365'/><link rel='alternate' type='text/html' href='http://jpmoresmau.blogspot.com/2010/02/waterloo-contest-and-human-intelligence.html' title='Waterloo Contest and Human Intelligence'/><author><name>JP Moresmau</name><uri>http://www.blogger.com/profile/09964251063221757176</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='26' height='32' src='http://4.bp.blogspot.com/_SFBL69b3jRQ/TIUvCsYa5EI/AAAAAAAAACw/4H33zrk1nAI/S220/shades.jpg'/></author><thr:total>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-37404288.post-940996296838273957</id><published>2010-02-01T16:20:00.002+01:00</published><updated>2010-02-01T16:30:01.407+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='IDE'/><category scheme='http://www.blogger.com/atom/ns#' term='Eclipse'/><category scheme='http://www.blogger.com/atom/ns#' term='self-publicity'/><category scheme='http://www.blogger.com/atom/ns#' term='Haskell'/><title type='text'>EclipseFP 1.110 released, with debugging support</title><content type='html'>Hello,&lt;br /&gt;I have released a &lt;a href="https://sourceforge.net/projects/eclipsefp/files/"&gt;new version&lt;/a&gt; of &lt;a href="http://eclipsefp.sourceforge.net/"&gt;EclipseFP&lt;/a&gt;. OK, I haven't kept to the one-release-a-month schedule, but with the Christmas season and everything, I deserved a break.&lt;br /&gt;I have fixed a few issues here and there (thanks for everybody who commented on the blog or used the Sourceforge tracker or forum), and tried to externalize strings into resources, but there's still a lot to be done on that subject.&lt;br /&gt;I have mainly worked at integrating the GHCi debugger with the Eclipse debugging framework. &lt;a href="http://www.eclipse.org/articles/Article-Debugger/how-to.html"&gt;This tutorial&lt;/a&gt; was really useful! Now what works is that you can set breakpoints in the source, and GHCi will stop at them if launched in debug mode in Eclipse. Once stopped (either via a breakpoint or if you use &lt;span style="font-family: courier new;"&gt;:step&lt;/span&gt;) you can see the bindings and force their evaluation (use the set value to variable function in Eclipse). You can also create some expressions and get them evaluated. Underneath with use GHCi commands like &lt;span style="font-family: courier new;"&gt;:show bindings&lt;/span&gt;, etc.&lt;br /&gt;I have removed some obsolete preferences and added debugging preferences (stop on error/exception, use show instances...).&lt;br /&gt;I'll be happy with any feedback on all these features. One thing missing is support for &lt;span style="font-family: courier new;"&gt;:hist&lt;/span&gt; when invoking &lt;span style="font-family: courier new;"&gt;:trace&lt;/span&gt;, tell me if you'd like that.&lt;br /&gt;Enjoy!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/37404288-940996296838273957?l=jpmoresmau.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jpmoresmau.blogspot.com/feeds/940996296838273957/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=37404288&amp;postID=940996296838273957' title='5 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/37404288/posts/default/940996296838273957'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/37404288/posts/default/940996296838273957'/><link rel='alternate' type='text/html' href='http://jpmoresmau.blogspot.com/2010/02/eclipsefp-1110-released-with-debugging.html' title='EclipseFP 1.110 released, with debugging support'/><author><name>JP Moresmau</name><uri>http://www.blogger.com/profile/09964251063221757176</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='26' height='32' src='http://4.bp.blogspot.com/_SFBL69b3jRQ/TIUvCsYa5EI/AAAAAAAAACw/4H33zrk1nAI/S220/shades.jpg'/></author><thr:total>5</thr:total></entry><entry><id>tag:blogger.com,1999:blog-37404288.post-977445446714174019</id><published>2009-11-23T17:41:00.003+01:00</published><updated>2009-11-23T17:49:04.898+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='IDE'/><category scheme='http://www.blogger.com/atom/ns#' term='self-publicity'/><category scheme='http://www.blogger.com/atom/ns#' term='Haskell'/><title type='text'>EclipseFP 1.109.0 is out!</title><content type='html'>A month exactly after the previous release, I got &lt;a href="https://sourceforge.net/projects/eclipsefp/files/"&gt;another release&lt;/a&gt; of &lt;a href="http://eclipsefp.sourceforge.net/"&gt;EclipseFP&lt;/a&gt; out! I tried to fix some of the issues that people reported, to improve the overall stability of the plugins and incorporated some new features that I hope could be useful (generation of extensions and ghc-options field in Cabal from the preferences, some quick fixes on GHC warnings...). I'll need feedback from users to know what features are really needed and could make a different to Haskell hackers.&lt;br /&gt;&lt;br /&gt;On a related note, I read that in "Coders at Work" &lt;a href="http://research.microsoft.com/en-us/people/simonpj/"&gt;Simon Peyton-Jones&lt;/a&gt; talks about the need for Visual Studio and Eclipse based IDEs to get more people interested in functional languages. I hope that my modest contribution helps...&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/37404288-977445446714174019?l=jpmoresmau.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jpmoresmau.blogspot.com/feeds/977445446714174019/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=37404288&amp;postID=977445446714174019' title='12 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/37404288/posts/default/977445446714174019'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/37404288/posts/default/977445446714174019'/><link rel='alternate' type='text/html' href='http://jpmoresmau.blogspot.com/2009/11/eclipsefp-11090-is-out.html' title='EclipseFP 1.109.0 is out!'/><author><name>JP Moresmau</name><uri>http://www.blogger.com/profile/09964251063221757176</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='26' height='32' src='http://4.bp.blogspot.com/_SFBL69b3jRQ/TIUvCsYa5EI/AAAAAAAAACw/4H33zrk1nAI/S220/shades.jpg'/></author><thr:total>12</thr:total></entry><entry><id>tag:blogger.com,1999:blog-37404288.post-8328675903059465984</id><published>2009-10-23T15:41:00.004+02:00</published><updated>2009-10-23T15:49:34.339+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='IDE'/><category scheme='http://www.blogger.com/atom/ns#' term='Java'/><category scheme='http://www.blogger.com/atom/ns#' term='Haskell'/><title type='text'>Releasing my code on the unsuspecting public (EclipseFP)</title><content type='html'>Today I've released a new version of &lt;a href="http://eclipsefp.sourceforge.net/"&gt;EclipseFP&lt;/a&gt; (Haskell support in Eclipse). There are quite a few changes in it, and there are even some changes in the &lt;a href="http://code.google.com/p/scion-lib/"&gt;Scion&lt;/a&gt; library that I've made and that &lt;a href="http://github.com/nominolo"&gt;Nominolo&lt;/a&gt; integrated. So people can give it a try if they want: get the current Scion source code, build/install it, and get the 1.108 version of EclipseFP.&lt;br /&gt;Hopefully that's another step for me in getting more proficient in Haskell: interacting with other Haskell hackers, learning from them and their code, and releasing code that may actually been of use to somebody (or annoy them no end if it doesn't work) instead of only a little &lt;a href="http://hackage.haskell.org/package/MazesOfMonad"&gt;game&lt;/a&gt; as before. And of course working on an Haskell IDE, even in Java, gets me to learn new things about the language, the options for Cabal or GHC, etc...&lt;br /&gt;Anyway, I hope I'll get some feedback on the new EclipseFP, and that we can move that thing forward!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/37404288-8328675903059465984?l=jpmoresmau.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jpmoresmau.blogspot.com/feeds/8328675903059465984/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=37404288&amp;postID=8328675903059465984' title='24 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/37404288/posts/default/8328675903059465984'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/37404288/posts/default/8328675903059465984'/><link rel='alternate' type='text/html' href='http://jpmoresmau.blogspot.com/2009/10/releasing-my-code-on-unsuspecting.html' title='Releasing my code on the unsuspecting public (EclipseFP)'/><author><name>JP Moresmau</name><uri>http://www.blogger.com/profile/09964251063221757176</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='26' height='32' src='http://4.bp.blogspot.com/_SFBL69b3jRQ/TIUvCsYa5EI/AAAAAAAAACw/4H33zrk1nAI/S220/shades.jpg'/></author><thr:total>24</thr:total></entry><entry><id>tag:blogger.com,1999:blog-37404288.post-1505346415888307766</id><published>2009-10-09T12:59:00.002+02:00</published><updated>2009-10-09T13:05:04.146+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='games'/><category scheme='http://www.blogger.com/atom/ns#' term='RIA'/><category scheme='http://www.blogger.com/atom/ns#' term='GUI'/><category scheme='http://www.blogger.com/atom/ns#' term='Haskell'/><title type='text'>What client for an Haskell Multi Player Game?</title><content type='html'>I've been thinking again, in between working on &lt;a href="http://eclipsefp.sourceforge.net/"&gt;eclipsefp&lt;/a&gt;, about writing a multi player role-playing game in Haskell. OK, I'm not going to write something the size of WoW by myself in my free time (unfortunately my day job doesn't involve any game programming nor any Haskell hacking :-(), but since I enjoyed writing &lt;a href="http://hackage.haskell.org/package/MazesOfMonad"&gt;Mazes of Monad&lt;/a&gt;, I figured that a game is a good way to learn things. A MMORPG should get me into concurrency, persistence, graphics, performance etc...&lt;br /&gt;&lt;br /&gt;What I'm trying to figure out at the moment is what architecture to use. Mainly, if I have no doubt there is going to be a server somewhere running Haskell code, I wonder about the client. Should I try to write a browser based game coupled with a Haskell web server? That way, users could easily play the game when (if) it gets to a usable state, and I won't have to worry about cross platform issues for the client. Getting proper server side events or push should be fun, and of course if I end up using something like &lt;a href="http://dev.w3.org/html5/websockets/"&gt;web sockets&lt;/a&gt; I will probably require a fairly cutting edge browser, which negates the advantage. I'm not too sure meddling with AJAX long polling and dynamic HTML is such a attractive option.&lt;br /&gt;The other path is to write a Haskell client. Granted, users will have to download it, which means either me dealing with cross platform issues (provide several exes) or restricting my users to people happy to use cabal install. But I'll get maybe into stuff like &lt;a href="http://www.haskell.org/haskellwiki/Opengl"&gt;OpenGL in Haskell&lt;/a&gt;, and do everything in Haskell instead of mixing Haskell with HTML and JavaScript (I've just stumbled upon &lt;a href="http://hackage.haskell.org/package/jmacro"&gt;jmacro&lt;/a&gt;, which could be cool I guess).&lt;br /&gt;&lt;br /&gt;I'm sure everybody has faced that question at some stage. Ah well, for the moment I'm still wondering what my game will do, so I guess I have time to play with a few things before I make my mind up.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/37404288-1505346415888307766?l=jpmoresmau.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jpmoresmau.blogspot.com/feeds/1505346415888307766/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=37404288&amp;postID=1505346415888307766' title='7 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/37404288/posts/default/1505346415888307766'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/37404288/posts/default/1505346415888307766'/><link rel='alternate' type='text/html' href='http://jpmoresmau.blogspot.com/2009/10/what-client-for-haskell-multi-player.html' title='What client for an Haskell Multi Player Game?'/><author><name>JP Moresmau</name><uri>http://www.blogger.com/profile/09964251063221757176</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='26' height='32' src='http://4.bp.blogspot.com/_SFBL69b3jRQ/TIUvCsYa5EI/AAAAAAAAACw/4H33zrk1nAI/S220/shades.jpg'/></author><thr:total>7</thr:total></entry><entry><id>tag:blogger.com,1999:blog-37404288.post-1275826448057756095</id><published>2009-09-28T08:53:00.002+02:00</published><updated>2009-09-28T08:56:50.335+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='IDE'/><category scheme='http://www.blogger.com/atom/ns#' term='Java'/><category scheme='http://www.blogger.com/atom/ns#' term='development'/><category scheme='http://www.blogger.com/atom/ns#' term='Scion'/><category scheme='http://www.blogger.com/atom/ns#' term='Eclipse'/><category scheme='http://www.blogger.com/atom/ns#' term='GHC'/><category scheme='http://www.blogger.com/atom/ns#' term='Haskell'/><title type='text'>Haskell development in Eclipse</title><content type='html'>I have started contributing to the &lt;a href="http://eclipsefp.sourceforge.net/"&gt;eclipsefp&lt;/a&gt; project. For those who don't know, it's a Eclipse-based environment for developing in Haskell.&lt;br /&gt;EclipseFP has had a troubled history so far. &lt;a href="http://cohatoe.blogspot.com/"&gt;Leif&lt;/a&gt; started the project and developed an impressive set of features. He then pursued the Cohatoe project to be able to write Eclipse plugins inm Haskell, in a effort to avoid rewriting in Java all kind of things that already existed in Haskell. And then this summer &lt;a href="http://eclipsefp.wordpress.com/"&gt;Thomas&lt;/a&gt; started integrating with &lt;a href="http://code.google.com/p/scion-lib/"&gt;Scion&lt;/a&gt;, which is a Haskell library that communicates with JSON data over simple sockets with non Haskell clients. Scion offers method to load Cabal projects, type check files, etc... That work is not finished, but Leif and Thomas have done such a great job that it's easy enough now to finish the missing bits here and there.&lt;br /&gt;This is perfect for me: part of the work is in Java and Eclipse, which is a lot of what I do in my day job, so I can bring a lot of experience there. Scion is a small enough library that need to be extended to provide me with all I want, so I can do little enhancements in Haskell and slowly build on features. And, last but not least, I need to learn the GHC API (which is what Scion uses to parse, check and compile files), to find what I need for.&lt;br /&gt;This will only enhance my knowledge of Haskell, and I hope that I'll be able to make something useful to provide Haskell hackers with another IDE to develop in.&lt;br /&gt;For those interested, the github repositories where my current work can be found are:&lt;br /&gt;&lt;br /&gt;&lt;a href="git://github.com/JPMoresmau/scion.git"&gt;git://github.com/JPMoresmau/scion.git&lt;/a&gt;&lt;br /&gt;&lt;a href="git://github.com/JPMoresmau/eclipsefp.git"&gt;git://github.com/JPMoresmau/eclipsefp.git&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/37404288-1275826448057756095?l=jpmoresmau.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jpmoresmau.blogspot.com/feeds/1275826448057756095/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=37404288&amp;postID=1275826448057756095' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/37404288/posts/default/1275826448057756095'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/37404288/posts/default/1275826448057756095'/><link rel='alternate' type='text/html' href='http://jpmoresmau.blogspot.com/2009/09/haskell-development-in-eclipse.html' title='Haskell development in Eclipse'/><author><name>JP Moresmau</name><uri>http://www.blogger.com/profile/09964251063221757176</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='26' height='32' src='http://4.bp.blogspot.com/_SFBL69b3jRQ/TIUvCsYa5EI/AAAAAAAAACw/4H33zrk1nAI/S220/shades.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-37404288.post-5564678178391950294</id><published>2009-08-07T11:40:00.002+02:00</published><updated>2009-08-07T11:45:56.357+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='self-indulgence'/><category scheme='http://www.blogger.com/atom/ns#' term='self-publicity'/><category scheme='http://www.blogger.com/atom/ns#' term='Haskell'/><category scheme='http://www.blogger.com/atom/ns#' term='game'/><title type='text'>Yoohoo: mazes of monad is kind of popular!</title><content type='html'>Don Stewart has published some statistics on packages popularity &lt;a href="http://donsbot.wordpress.com/2009/08/06/haskell-package-popularity-rankings-august-2009/"&gt;here &lt;/a&gt;. &lt;a href="http://hackage.haskell.org/package/MazesOfMonad"&gt;MazesOfMonad&lt;/a&gt; is the fastest rising application over the past 4 months. Thanks to all people who downloaded it, hope you enjoyed it, feel free to send me bug reports or enhancement requests. Hopefully I'll find the free time (in between day work, family, sports, etc.) to develop another more ambitious game in the coming months!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/37404288-5564678178391950294?l=jpmoresmau.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jpmoresmau.blogspot.com/feeds/5564678178391950294/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=37404288&amp;postID=5564678178391950294' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/37404288/posts/default/5564678178391950294'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/37404288/posts/default/5564678178391950294'/><link rel='alternate' type='text/html' href='http://jpmoresmau.blogspot.com/2009/08/yoohoo-mazes-of-monad-is-kind-of.html' title='Yoohoo: mazes of monad is kind of popular!'/><author><name>JP Moresmau</name><uri>http://www.blogger.com/profile/09964251063221757176</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='26' height='32' src='http://4.bp.blogspot.com/_SFBL69b3jRQ/TIUvCsYa5EI/AAAAAAAAACw/4H33zrk1nAI/S220/shades.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-37404288.post-2991245061658188175</id><published>2009-07-10T14:31:00.003+02:00</published><updated>2009-07-10T14:43:27.425+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Artificial Intelligence'/><category scheme='http://www.blogger.com/atom/ns#' term='Haskell'/><category scheme='http://www.blogger.com/atom/ns#' term='game'/><title type='text'>Mazes of Monad: 1.0.5 and (maybe) final version uploaded</title><content type='html'>I've uploaded yesterday on &lt;a href="http://hackage.haskell.org/package/MazesOfMonad"&gt;Hackage&lt;/a&gt; the 1.0.5 version of my Role Playing Game called Mazes of Monad. I think this will be the last upload unless some big bugs are found. But I think I'll stop here in terms of functionality. It was fun, I learned a lot about Haskell, both on programming with the language, and on how to design Haskell code. Working on a full project over a long period of time forced me to actually understand code I had written previously and make it evolve instead of just having a clean slate.&lt;br /&gt;&lt;br /&gt;I also realized than while developing a game is a lot of fun, the actual programming is the, ahem, easy part. I find that the actual game design (how to get usable and useful features) and the tweaking of the difficulty, for example, are the most challenging. For a while my test character was quite a strong warrior and I thought the game was easy, so I changed some settings to make it harder, then I realized that I had made it quite hard to start with a poor naked wizard that knew only one spell... I can see that balancing all the different game settings  and getting the right formulas is critical, and that only comes from testing and collecting feedback...&lt;br /&gt;&lt;br /&gt;Anyway, I have ideas for other games, probably the next one will be web based to have some kind of GUI and be multi player, maybe using &lt;a href="http://happstack.com/"&gt;happstack&lt;/a&gt; as the server (or should I just use a little home grown server in Haskell, for fun?). I'll keep on posting about that!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/37404288-2991245061658188175?l=jpmoresmau.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jpmoresmau.blogspot.com/feeds/2991245061658188175/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=37404288&amp;postID=2991245061658188175' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/37404288/posts/default/2991245061658188175'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/37404288/posts/default/2991245061658188175'/><link rel='alternate' type='text/html' href='http://jpmoresmau.blogspot.com/2009/07/mazes-of-monad-105-and-maybe-final.html' title='Mazes of Monad: 1.0.5 and (maybe) final version uploaded'/><author><name>JP Moresmau</name><uri>http://www.blogger.com/profile/09964251063221757176</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='26' height='32' src='http://4.bp.blogspot.com/_SFBL69b3jRQ/TIUvCsYa5EI/AAAAAAAAACw/4H33zrk1nAI/S220/shades.jpg'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-37404288.post-8294441494442743961</id><published>2009-05-15T16:00:00.002+02:00</published><updated>2009-05-15T16:17:17.153+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Monads'/><category scheme='http://www.blogger.com/atom/ns#' term='games'/><category scheme='http://www.blogger.com/atom/ns#' term='Haskell'/><title type='text'>Adding a Writer Monad transformer</title><content type='html'>I'm still working on MazesOfMonad, my Haskell RPG, now on &lt;a href="http://code.haskell.org/MazesOfMonad/"&gt;code.haskell.org&lt;/a&gt;. It's actually fun to now have a working program and think about extensions in functionality, and then how to implement them in Haskell, instead of just playing around with the language.&lt;br /&gt;I wanted to give the user more feedback that they currently got about what was going on in the game, and at the same time I wasn't happy with what I had written previously: I had the output messages as part of the method signature:&lt;br /&gt;&lt;br /&gt;myFunction :: Type1 -&gt; Type2 -&gt; (Type3,[String])&lt;br /&gt;&lt;br /&gt;So I decided a Monad was called for. The Writer Monad, in this case, which lets us append stuff together to get it all back at the end. I already had most of my game running in a monad transformer, so it was **just** a matter of figuring out how to wrap everything in a WriterT. I had a bit of fun at first, then got it working. So now my game runs in a&lt;br /&gt;&lt;br /&gt;WriterT a (RandT (StateT b IO)) c&lt;br /&gt;&lt;br /&gt;Where a b a are various types for the things I need: a is the type of messages I write, b the state I keep, and c the return value. RandT gives me random numbers, StateT gives me a state, IO allows me to do IO operations when I need to save the game or something like that.&lt;br /&gt;&lt;br /&gt;The amazing thing, well, for me, is that a lot of my functions do not need to be aware of the whole transformer stack, but of only the type classes that they care about. My final transformer is an instance of both MonadWriter and MonadRandom. So my method that needs to write messages becomes:&lt;br /&gt;&lt;br /&gt;myFunction :: (MonadWriter [String] m)=&gt;Type1 -&gt; Type2 -&gt; m Type3&lt;br /&gt;&lt;br /&gt;And I can write my code calling the MonadWriter methods to add messages. It's in a monad, but it's still purely functional: I return a Type3 object and write Strings. If my function needs random numbers:&lt;br /&gt;&lt;br /&gt;myFunction :: (MonadRandom m, MonadWriter [String] m)=&gt;Type1 -&gt; Type2 -&gt; m Type3&lt;br /&gt;&lt;br /&gt;and I get random numbers capabilities!&lt;br /&gt;&lt;br /&gt;The final code is now much cleaner than before (I actually don't use [String] directly for the MonadWriter type but an alias for it, so I can replace it with Seq String or something faster the day I fancy it). I think I now understand monads and monad type classes better, and I understand better how using a monad doesn't automatically mean using the IO Monad and lose purity. Haskell Nirvana is not far off, says he naively...&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/37404288-8294441494442743961?l=jpmoresmau.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jpmoresmau.blogspot.com/feeds/8294441494442743961/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=37404288&amp;postID=8294441494442743961' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/37404288/posts/default/8294441494442743961'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/37404288/posts/default/8294441494442743961'/><link rel='alternate' type='text/html' href='http://jpmoresmau.blogspot.com/2009/05/adding-writer-monad-transformer.html' title='Adding a Writer Monad transformer'/><author><name>JP Moresmau</name><uri>http://www.blogger.com/profile/09964251063221757176</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='26' height='32' src='http://4.bp.blogspot.com/_SFBL69b3jRQ/TIUvCsYa5EI/AAAAAAAAACw/4H33zrk1nAI/S220/shades.jpg'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-37404288.post-7440691294050845083</id><published>2009-04-27T16:40:00.003+02:00</published><updated>2009-04-27T16:50:00.451+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='games'/><category scheme='http://www.blogger.com/atom/ns#' term='Artificial Intelligence'/><category scheme='http://www.blogger.com/atom/ns#' term='Haskell'/><title type='text'>Haskell RPG Game uploaded on Hackage!</title><content type='html'>&lt;span style="font-family: verdana;"&gt;I've worked on it on and off for months, I've rewritten parts of it entirely, it gave me the opportunity to knock together a real, complete application in Haskell, and it's finally done! I've uploaded my console based RPG game (read: nethack clone) to Hackage (get it &lt;/span&gt;&lt;a style="font-family: verdana;" href="http://hackage.haskell.org/cgi-bin/hackage-scripts/package/MazesOfMonad-1.0"&gt;here&lt;/a&gt;&lt;span style="font-family: verdana;"&gt;). You create a character and walk through mazes, trading, stealing, casting spells and fighting monsters.&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: verdana;"&gt;You can look at the source code (no documentation, sorry) and see what I've used. I've used a monad to abstract away the state and the random generator (so I can plug a non random generator for testing, one that for example will guarantee that the next throw of the D20 die will give 8). I have developped my own little framework for console handling (executing actions from what the user typed in and displaying results) maybe I should look at the existing libraries and try to plug one in instead. &lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: verdana;"&gt;What I found was the most awkward was the record syntax for nested structures, I'll have to investigate to find an easier way to read and update my structures. &lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: verdana;"&gt;There are a few HUnit tests to verify that the most basic functionality works, so hopefully there is no huge bug.&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: verdana;"&gt;It was fun to play around with Haskell and with game concepts. I hope I'll have time to work on even cooler stuff like adding AI for the monsters (so they can decide when to run away, etc...).&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: verdana;"&gt;Any feedback on the game mechanism or on the code itself is welcome!&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/37404288-7440691294050845083?l=jpmoresmau.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jpmoresmau.blogspot.com/feeds/7440691294050845083/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=37404288&amp;postID=7440691294050845083' title='7 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/37404288/posts/default/7440691294050845083'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/37404288/posts/default/7440691294050845083'/><link rel='alternate' type='text/html' href='http://jpmoresmau.blogspot.com/2009/04/haskell-rpg-game-uploaded-on-hackage.html' title='Haskell RPG Game uploaded on Hackage!'/><author><name>JP Moresmau</name><uri>http://www.blogger.com/profile/09964251063221757176</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='26' height='32' src='http://4.bp.blogspot.com/_SFBL69b3jRQ/TIUvCsYa5EI/AAAAAAAAACw/4H33zrk1nAI/S220/shades.jpg'/></author><thr:total>7</thr:total></entry><entry><id>tag:blogger.com,1999:blog-37404288.post-5716534815389729354</id><published>2009-02-27T15:28:00.003+01:00</published><updated>2009-02-27T15:57:44.690+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='GUI'/><category scheme='http://www.blogger.com/atom/ns#' term='Haskell'/><title type='text'>A high-level GUI library for Haskell</title><content type='html'>&lt;span style="font-size:85%;"&gt;&lt;span style="font-family: verdana;"&gt;There seems to still be a void in the Haskell world regarding GUI libraries. On one hand we have low level libraries based on well know solutions but doing everything in the IO monad, to cut short, on another functional reactive libraries that just don't seem to be accessible for haskell programmers of my level, somehow... And I'm not the only one: just the other day I saw a new attempt being made at a functional easy to use GUI library: &lt;/span&gt;&lt;a style="font-family: verdana;" href="http://hackage.haskell.org/cgi-bin/hackage-scripts/package/barrie"&gt;Barrie.&lt;/a&gt;&lt;span style="font-family: verdana;"&gt; It looks promising, but I had already started my own, so I think I'm going to continue a little bit, I find I'm learning a lot in the process...&lt;/span&gt;&lt;br/&gt;&lt;br /&gt;&lt;span style="font-family: verdana;"&gt;The ideas being my own library, tentatively called UITree are the following:&lt;br /&gt;&lt;/span&gt;&lt;br/&gt;&lt;span style="font-family: verdana;"&gt;- you build your GUI using combinators that start from simple widgets and use composite widgets and layouts to augment a tree&lt;br /&gt;&lt;/span&gt;&lt;span style="font-family: verdana;"&gt;- event handler can be attached to widgets in the tree. The handlers are of type (ui, state)-&gt;IO(ui,state): you get the current ui tree and the current state, and you transform them. The IO bit is to allow you to do IO actions if you want but you can do without.&lt;/span&gt;&lt;br/&gt;&lt;br /&gt;&lt;span style="font-family: verdana;"&gt;- inside the event handlers you manipulate the ui tree a bit like &lt;/span&gt;&lt;a style="font-family: verdana;" href="http://jquery.com/"&gt;JQuery&lt;/a&gt;&lt;span style="font-family: verdana;"&gt; does with HTML DOM: you can select particular widgets, operate on them, etc... Most operations are just transformers from the UITree type to the same type, so you can chain them.&lt;br /&gt;&lt;/span&gt;&lt;br/&gt;&lt;span style="font-family: verdana;"&gt;- since you can't reference directly the widgets in your fonctional tree, you can give them explicit ids, so there is a disconnect between the actual tree and the handlers, which is similar to JQuery (you cannot rely on the compiler to make sure you manipulate an existing widget).&lt;br /&gt;&lt;/span&gt;&lt;br/&gt;&lt;br /&gt;&lt;span style="font-family: verdana;"&gt;For the moment I got some small samples to work with WXWidgets (Barrie uses GTK, by the way).&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: verdana;"&gt;The API is bound to change, but this is how a frame containing a close button and a button that increases a internal integer state  and displays the current state:&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;simpleState :: IO (Int)&lt;br /&gt;simpleState=do&lt;br /&gt; start simpleUI 0 -- start the WXWidgets UI with the given UI tree and initial state&lt;br /&gt;   where&lt;br /&gt;     simpleUI=(frame [text := "Simple"])  --  the enclosing frame&lt;br /&gt;        (&lt;br /&gt;         (panel [])  -- a panel to enclose our children&lt;br /&gt;            (row [space := 5] -- children in a row, a bit of space&lt;br /&gt;             [&lt;br /&gt;               (button [text := "0"] [command :&gt; (return . doInc)]),  -- a button showing 0 and increasing the state when clicked&lt;br /&gt;               (button [wid:="close", text := "Close!"] [command :&gt; (pureUI doClose)]) -- a button to close the frame, pureUI is just a helper function that shows we're not modifying the state&lt;br /&gt;             ]&lt;br /&gt;             )&lt;br /&gt;           )&lt;br /&gt;     doInc (tree,st)=(set [text := (show (st+1))] tree,(st+1)) -- set the button text and state to state + 1&lt;br /&gt;     doClose tree=close $ top tree -- close the top of the tree (the frame)&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="font-family: verdana;"&gt;Note how the ui building and the handlers are pure functions, so you just manipulate your tree and your state.&lt;/span&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/37404288-5716534815389729354?l=jpmoresmau.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jpmoresmau.blogspot.com/feeds/5716534815389729354/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=37404288&amp;postID=5716534815389729354' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/37404288/posts/default/5716534815389729354'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/37404288/posts/default/5716534815389729354'/><link rel='alternate' type='text/html' href='http://jpmoresmau.blogspot.com/2009/02/high-level-gui-library-for-haskell.html' title='A high-level GUI library for Haskell'/><author><name>JP Moresmau</name><uri>http://www.blogger.com/profile/09964251063221757176</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='26' height='32' src='http://4.bp.blogspot.com/_SFBL69b3jRQ/TIUvCsYa5EI/AAAAAAAAACw/4H33zrk1nAI/S220/shades.jpg'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-37404288.post-6801923161157020397</id><published>2008-11-28T14:07:00.001+01:00</published><updated>2008-11-28T14:10:41.319+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='games'/><category scheme='http://www.blogger.com/atom/ns#' term='Functional Programming'/><category scheme='http://www.blogger.com/atom/ns#' term='Haskell'/><title type='text'>Predictable random for testing</title><content type='html'>In my Haskell RPG game, the results of actions are random: I use the standard random generator to simulate the throw of a dice in a table top RPG.&lt;br /&gt;However for writing &lt;a href="http://hackage.haskell.org/cgi-bin/hackage-scripts/package/HUnit"&gt;unit tests&lt;/a&gt; that is not ideal, since I would like to be able to test the outcome of an action for a given result of the dice. I didn't &lt;br /&gt;want to clutter the code (even if using a State monad) with something used only for testing, so I experimented with &lt;a href="http://haskell.org/ghc/docs/latest/html/libraries/base/Data-IORef.html"&gt;IORef&lt;/a&gt; and a custom Test Generator.&lt;br /&gt;&lt;br /&gt;First of all, we need a data type to store our non random random generator. It will store a list of results and the index it's at in that list. It's &lt;br /&gt;basically a circular list, so that when we reach the end we start again. If the list is one element long, then the same result will be given for all &lt;br /&gt;dice throws:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;data TestGen = TestGen [Int] Int&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;mkTestGen is just a helper function to initialise the index to 0&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;mkTestGen l=TestGen l 0&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;This is the real magic: I thought you needed to pass around an IORef as any other variable to be able to read its results, but in fact this is not necessary,&lt;br /&gt;if somewhat of a &lt;a href="http://www.haskell.org/haskellwiki/Top_level_mutable_state"&gt;kludge&lt;/a&gt;:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;testGen :: IORef (TestGen)&lt;br /&gt;{-# NOINLINE testGen #-}&lt;br /&gt;testGen=unsafePerformIO (newIORef (mkTestGen []))&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;This means that testGen is initialized only once as a TestGen with an empty list, no matter how many time it's called. It seemed to work in ghci even &lt;br /&gt;without the NOINLINE pragma. Don't ask me why. So, given a simple setter function:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;setTestGen l=do&lt;br /&gt; writeIORef testGen (mkTestGen l)&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;We can specify what we want as the random generator. If we have an empty list, we use the standard random generator, otherwise we return the current element &lt;br /&gt;in the list, and increment the index, going back to zero if we overrun the list:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;randomInt ::(Int,Int) -&gt; IO (Int) &lt;br /&gt;randomInt (l,h)=do&lt;br /&gt; (TestGen list ix)&amp;lt;-readIORef testGen &lt;br /&gt; if null list&lt;br /&gt;  then getStdRandom (randomR (l,h))&lt;br /&gt;  else do&lt;br /&gt;   let e=list!!ix&lt;br /&gt;   let ix'=ix+1&lt;br /&gt;   let ix''=if ix'==(length list)&lt;br /&gt;    then 0&lt;br /&gt;    else ix'&lt;br /&gt;   writeIORef testGen (TestGen list ix'')&lt;br /&gt;   if e&amp;lt;l || e&amp;gt;h&lt;br /&gt;    then error (printf "%d not in range (%d,%d)" e l h)&lt;br /&gt;    else return e&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;And this works, amazingly:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt; setTestGen [2]&lt;br /&gt; l&amp;lt;-replicateM 3 (randomInt (1,6))&lt;br /&gt; assertEqual ("l is not 3 2s") [2,2,2] l&lt;br /&gt; setTestGen [2,3,4]&lt;br /&gt; l&amp;lt;-replicateM 4 (randomInt (1,6))&lt;br /&gt; assertEqual ("l is not 2,3,4,2") [2,3,4,2] l&lt;br /&gt; setTestGen []&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;(Notice how I reset the test generator to standard at the end by passing an empty list).&lt;br /&gt;&lt;br /&gt;So now I can test my code with predictable results, that will be still random in production use. &lt;br /&gt;Oops, already found a bug on the first test written with that technique!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/37404288-6801923161157020397?l=jpmoresmau.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jpmoresmau.blogspot.com/feeds/6801923161157020397/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=37404288&amp;postID=6801923161157020397' title='7 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/37404288/posts/default/6801923161157020397'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/37404288/posts/default/6801923161157020397'/><link rel='alternate' type='text/html' href='http://jpmoresmau.blogspot.com/2008/11/predictable-random-for-testing.html' title='Predictable random for testing'/><author><name>JP Moresmau</name><uri>http://www.blogger.com/profile/09964251063221757176</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='26' height='32' src='http://4.bp.blogspot.com/_SFBL69b3jRQ/TIUvCsYa5EI/AAAAAAAAACw/4H33zrk1nAI/S220/shades.jpg'/></author><thr:total>7</thr:total></entry><entry><id>tag:blogger.com,1999:blog-37404288.post-7180485724192777358</id><published>2008-11-03T22:06:00.005+01:00</published><updated>2008-11-03T22:20:33.998+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='maths'/><category scheme='http://www.blogger.com/atom/ns#' term='Haskell'/><title type='text'>Haskell for counting votes!</title><content type='html'>There's apparently an important election going on in the States. There are also a few interesting articles, for example in the french maths magazine Tangente (no up to date online edition that I could find unfortunately) and in the &lt;a href="http://www.newscientist.com/channel/being-human/mg19826511.600-why-firstpastthepost-voting-is-flawed.html"&gt;New Scientist&lt;/a&gt;, on how the way you tally votes affect the outcome. Tangente has a stiking example, and I'll go through the 5 vote couting methods they outline with an Haskell implementation of each.&lt;br /&gt;No pesky elephant vs donkey, here, the election is about your favorite female movie star:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;data Star = MarylinMonroe | AngelinaJolie | BrigitteBardot | EmmanuelleBeart | ClaudiaCardinale&lt;br /&gt; deriving (Show,Read,Eq,Bounded,Enum,Ord,Ix)&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Note the "deriving Ix" (from &lt;a href="http://www.haskell.org/ghc/docs/latest/html/libraries/array/Data-Array-IArray.html"&gt;Data.Array.IArray&lt;/a&gt;) so we can use the stars as array indices.&lt;br /&gt;&lt;br /&gt;We have six elector profiles: each profile has ranked the stars in order of preferences, and we have the numbers (in millions, say) of electors for that profile. For example, 7.2 million people prefer MarylinMonroe, then Emanuelle Beart, then Claudia Cardinale, 4.8 millions prefer Angelina Jolie, etc. Here's the full data:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;votes :: [(Double,[Star])]&lt;br /&gt;votes = [&lt;br /&gt; (7.2,[MarylinMonroe,EmmanuelleBeart,ClaudiaCardinale,BrigitteBardot,AngelinaJolie]),&lt;br /&gt; (4.8,[AngelinaJolie,ClaudiaCardinale,EmmanuelleBeart,BrigitteBardot,MarylinMonroe]),&lt;br /&gt; (4,[BrigitteBardot,AngelinaJolie,ClaudiaCardinale,EmmanuelleBeart,MarylinMonroe]),&lt;br /&gt; (3.6,[EmmanuelleBeart,BrigitteBardot,ClaudiaCardinale,AngelinaJolie,MarylinMonroe]),&lt;br /&gt; (1.6,[ClaudiaCardinale,AngelinaJolie,EmmanuelleBeart,BrigitteBardot,MarylinMonroe]),&lt;br /&gt; (0.8,[ClaudiaCardinale,BrigitteBardot,EmmanuelleBeart,AngelinaJolie,MarylinMonroe])&lt;br /&gt; ]&lt;/pre&gt;&lt;br /&gt; &lt;br /&gt;With this we need a few helper method before we're ready to implement our voting algorithms.&lt;br /&gt;&lt;br /&gt;We need a way to tally votes for stars, taking into account that several profiles may vote for the same star at the same round (Claudia Cardinale at the first round, say). We use an array with the addition as accumulation function, sorted my popularity&lt;br /&gt;&lt;pre&gt;accumVotes ::  [(Star,Double)] -&gt;  [(Star,Double)]&lt;br /&gt;accumVotes v=let&lt;br /&gt; arr=(accumArray (+) 0 (MarylinMonroe,ClaudiaCardinale) v):: Array Star Double&lt;br /&gt; in sortBy (\a b -&gt; compare (snd b) (snd a)) (assocs arr)&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;For some reason I needed to tell GHC about the array type, it couldn't infer it.&lt;br /&gt;We need a way to get the votes for a given round (even if we'll only be using the first round this way)&lt;br /&gt;&lt;pre&gt;roundResults :: Int -&gt; [(Star,Double)]&lt;br /&gt;roundResults r=let&lt;br /&gt; v=map (\(a,b)-&gt;(b !! r,a)) votes&lt;br /&gt; in accumVotes v&lt;/pre&gt;&lt;br /&gt; &lt;br /&gt;And a simple extraction function to get the winner's name from accumulated votes: &lt;br /&gt;&lt;pre&gt;bestVote ::[(Star,Double)] -&gt; Star&lt;br /&gt;bestVote v= fst $ head $ (accumVotes v)&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Now we're ready. The first algorith is a simple one round voting election:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;oneRound :: Star&lt;br /&gt;oneRound=bestVote (roundResults 0)&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;This makes Marylin Monroe the clear winner. But a lot of countries use a two round system: the most popular candidates after the first round make it through to the second round:&lt;br /&gt;&lt;br /&gt;We first need a helper function that retrieves the first element from a first list found in a second list (is there a standard method somewhere?)&lt;br /&gt;&lt;pre&gt;findFirst :: Eq a =&gt; [a] -&gt; [a] -&gt; a &lt;br /&gt;findFirst toFind (a:rest) =  if elem a toFind&lt;br /&gt; then a&lt;br /&gt; else findFirst toFind rest&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Then it's straightforward: we get the first two candidates after the first round, and accumulate their results over all the profiles&lt;br /&gt;&lt;pre&gt;twoRounds :: Star&lt;br /&gt;twoRounds= let&lt;br /&gt; (fr1:fr2:_)=(roundResults 0)&lt;br /&gt; allScores=map (\(a,b)-&gt;(findFirst [fst fr1,fst fr2] b,a)) votes&lt;br /&gt; in bestVote allScores&lt;/pre&gt;&lt;br /&gt; &lt;br /&gt;Angelina Jolie for President! A third method we can use is to proceed by elimination: at each round, we drop the least popular candidate, until we get only one:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;elimination :: Star&lt;br /&gt;elimination=  fst $ elimination' (roundResults 0)&lt;br /&gt; where&lt;br /&gt;  elimination' ::  [(Star,Double)] -&gt; (Star,Double)&lt;br /&gt;  elimination' (a:b:[])=a&lt;br /&gt;  elimination' l= let&lt;br /&gt;   firstRound= map fst $ init l&lt;br /&gt;   in elimination' $ filter (\a-&gt;(snd a) &gt;0.0 ) $ accumVotes $ map (\(a,b)-&gt;(findFirst firstRound b,a)) votes&lt;/pre&gt;&lt;br /&gt; &lt;br /&gt;This little recursivity yields Brigitte Bardot. &lt;a href="http://en.wikipedia.org/wiki/Borda_count"&gt;Borda&lt;/a&gt; suggested another method: we assign a weight to each candidate depending on its ranking, that weight is used as a multiplier of the votes. First choice gets a total tally of the votes times 5, second choice 4, etc.&lt;br /&gt; &lt;br /&gt;&lt;pre&gt;borda :: Star&lt;br /&gt;borda = bestVote $ concat $ map (\(a,ss)-&gt; map (\(s,mul)-&gt;(s,mul*a)) (zip ss [5,4 .. 1])) votes&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;And this time, Emanuelle Béart comes on top! Last method we will survey is from &lt;a href="http://en.wikipedia.org/wiki/Condorcet_method"&gt;Condorcet&lt;/a&gt;: we look at each match bewteen two stars in isolation. A match is won if more votes put the first star in front of the second star. We first calculate all the possible matches than consider each won match as 1 vote, and accumulate as before:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;condorcet :: Star&lt;br /&gt;condorcet= let&lt;br /&gt; matches=[[x,y] | x &lt;-allStars, y &lt;- tail [x .. ClaudiaCardinale]]&lt;br /&gt; matchResults= map (\match-&gt;(bestVote $ map (\(a,b)-&gt;(findFirst match b,a)) votes,1)) matches&lt;br /&gt; in bestVote matchResults&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;And, behold, the winner through this method is... Claudia Cardinale! Five methods, five winners!&lt;br /&gt;Of course these are really quick draft of voting methods, they should take into accound draws, etc... Do not use this code to elect the president of a real country!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/37404288-7180485724192777358?l=jpmoresmau.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jpmoresmau.blogspot.com/feeds/7180485724192777358/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=37404288&amp;postID=7180485724192777358' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/37404288/posts/default/7180485724192777358'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/37404288/posts/default/7180485724192777358'/><link rel='alternate' type='text/html' href='http://jpmoresmau.blogspot.com/2008/11/haskell-for-counting-votes.html' title='Haskell for counting votes!'/><author><name>JP Moresmau</name><uri>http://www.blogger.com/profile/09964251063221757176</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='26' height='32' src='http://4.bp.blogspot.com/_SFBL69b3jRQ/TIUvCsYa5EI/AAAAAAAAACw/4H33zrk1nAI/S220/shades.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-37404288.post-4733485267497120748</id><published>2008-09-02T20:54:00.002+02:00</published><updated>2008-09-02T21:01:17.181+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='performance'/><category scheme='http://www.blogger.com/atom/ns#' term='Functional Programming'/><category scheme='http://www.blogger.com/atom/ns#' term='Haskell'/><title type='text'>Arrays to the rescue!</title><content type='html'>&lt;a style="font-family: arial;" href="http://jpmoresmau.blogspot.com/2008/01/scraping-my-boilerplate-generics.html"&gt;Some time ago&lt;/a&gt;&lt;span style="font-family: arial;"&gt; I blogged about &lt;/span&gt;&lt;a style="font-family: arial;" href="http://www.haskell.org/ghc/docs/latest/html/libraries/base/Data-Generics.html"&gt;Haskell Generics&lt;/a&gt;&lt;span style="font-family: arial;"&gt; and how they simplified my code of a little RPG game I'm writing. My data types were designed with lists. For example a character has traits, and traits are a list of Characteristic objects, that have a name (Strength, Dexterity, etc.) and values. The Generics code helped me to deal with finding the right item in the list depending on the name, updating its value, etc. Records were no good because you can pass the generated function as an accessor but not as a mutator.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: arial;"&gt;I have some unit tests that generate random characters, and I thought they were pretty slow, which I thought was due to the random number generator. Then I ran the tests with profiling on. Guess what? The Generics code amounted for a huge amount of the time spent. And I'd say the underlying list operation, with loads of list updates, were not great either.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: arial;"&gt;So I got rid of the Generics code, and I decided to replace my lists by something else. In the Java world (my day time job) I rely heavily on Maps. I thought it was a bit overkill in this case, so I turned to the &lt;/span&gt;&lt;a style="font-family: arial;" href="http://www.haskell.org/ghc/docs/latest/html/libraries/array/Data-Array-IArray.html"&gt;Haskell array&lt;/a&gt;&lt;span style="font-family: arial;"&gt; package. And there was light!&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: arial;"&gt;You see, Arrays in Haskell are a different beast that arrays in other languages. You can use different types for the indices, not only integers. So since the data type representing the names of characteristics is a simple enumeration, I could use that as the array index. So the characters traits are an array with the names as indices:&lt;/span&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;data Characteristic = Strength | Dexterity | ...&lt;br /&gt;  deriving (Show,Read,Eq,Enum,Bounded,Ord,Ix)&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;span style="font-family: arial;"&gt;Ix is the type class that an array index type must implement&lt;/span&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;type CharacteristicRatings=Array Characteristic Rating&lt;br /&gt;&lt;br /&gt;data Character = Character {&lt;br /&gt;  ...&lt;br /&gt;  ,traits::CharacteristicRatings&lt;br /&gt;  ...&lt;br /&gt;  }&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;span style="font-family: arial;"&gt;And Rating follow the same pattern, since a rating has the current value for the characteristic, the normal value, etc.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: arial;"&gt;Then the array operations make it easy enough to read and modify values: ! to get the value at the specified index, // to update. I get type safety and expressiveness (no need to even use toEnum and fromEnum), and performance...&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: arial;"&gt;Performance? With the Generics code and lists, my tests took 8 seconds. With arrays and no Generics, 0.26s. Nuff said.&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/37404288-4733485267497120748?l=jpmoresmau.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jpmoresmau.blogspot.com/feeds/4733485267497120748/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=37404288&amp;postID=4733485267497120748' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/37404288/posts/default/4733485267497120748'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/37404288/posts/default/4733485267497120748'/><link rel='alternate' type='text/html' href='http://jpmoresmau.blogspot.com/2008/09/arrays-to-rescue.html' title='Arrays to the rescue!'/><author><name>JP Moresmau</name><uri>http://www.blogger.com/profile/09964251063221757176</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='26' height='32' src='http://4.bp.blogspot.com/_SFBL69b3jRQ/TIUvCsYa5EI/AAAAAAAAACw/4H33zrk1nAI/S220/shades.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-37404288.post-5472058645575689613</id><published>2008-07-11T13:31:00.001+02:00</published><updated>2008-07-11T13:33:23.885+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Functional Programming'/><category scheme='http://www.blogger.com/atom/ns#' term='JSON'/><category scheme='http://www.blogger.com/atom/ns#' term='generics'/><category scheme='http://www.blogger.com/atom/ns#' term='Haskell'/><title type='text'>instance Data Map where -- half done!</title><content type='html'>While testing my JSON serializer/deserializer, I made the (unpleasant) discovery  that some standard structures (most notable Data.Map.Map) do not implement all of Data.Generics.Data interface. They just call error on things like toConstr and gunfold. Which is not good, since I use these methods. Why they can't just pretend that a Map K v is for generics a map of (k,v) I don't understand (they implement gfoldl that way), but hey, I'm only a humble learner of Haskell...&lt;br /&gt;&lt;br /&gt;So I spent a few hours trying to modify my JSON code to work around this issue, to no avail (well I can get the serialization all right, but the deserialization seems to be tricky). So I've got another approach to work: since the default for Data instances is not right when your objects contains Map structures, lets rewrite these... Using the source for Data.Map and the documentation for Data.Generics.Data, I managed to get it to work, but of course the price is loads (loads, loads) of boilerplate code.&lt;br /&gt;&lt;br /&gt;So here goes: I have the simple object: (assume import qualified Data.Map as M)&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;data MapObjF=MapObjF (M.Map String Int) String&lt;br /&gt; deriving (Eq,Typeable,Show)&lt;/pre&gt;&lt;br /&gt; &lt;br /&gt;So MapObjF contains a Map String Integer and a String&lt;br /&gt;&lt;br /&gt;And here's the Data instance definition (big breath):&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;instance Data MapObjF where&lt;br /&gt;     gfoldl k z (MapObjF m s) = k (k (z (MapObjF . M.fromList)) (M.toList m)) s&lt;br /&gt;     gunfold k z _ = k (k (z (MapObjF . M.fromList)))&lt;br /&gt;     toConstr (MapObjF _ _) = con_MapObjF&lt;br /&gt;     dataTypeOf _ = ty_MapObjF&lt;br /&gt;&lt;br /&gt;con_MapObjF = mkConstr ty_MapObjF "MapObjF" [] Prefix&lt;br /&gt;ty_MapObjF   = mkDataType "MyModule.MapObjF" [con_MapObjF]&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;I define the constructor, the datatype, and implement gfoldl and gunfold transforming the map into a list of tuples. Of course if you have several constructors, loads of fields it soon becomes unwieldy. Now, is there a Haskell macro system so I can easily generate all that boilerplate for all my data types? Noooo I don't want to leave Haskell for LISP...&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/37404288-5472058645575689613?l=jpmoresmau.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jpmoresmau.blogspot.com/feeds/5472058645575689613/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=37404288&amp;postID=5472058645575689613' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/37404288/posts/default/5472058645575689613'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/37404288/posts/default/5472058645575689613'/><link rel='alternate' type='text/html' href='http://jpmoresmau.blogspot.com/2008/07/instance-data-map-where-half-done.html' title='instance Data Map where -- half done!'/><author><name>JP Moresmau</name><uri>http://www.blogger.com/profile/09964251063221757176</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='26' height='32' src='http://4.bp.blogspot.com/_SFBL69b3jRQ/TIUvCsYa5EI/AAAAAAAAACw/4H33zrk1nAI/S220/shades.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-37404288.post-1123342167001103987</id><published>2008-07-08T13:17:00.002+02:00</published><updated>2008-07-08T13:21:24.523+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Functional Programming'/><category scheme='http://www.blogger.com/atom/ns#' term='JSON'/><category scheme='http://www.blogger.com/atom/ns#' term='Haskell'/><title type='text'>Handling errors in JSON to Haskell deserialization</title><content type='html'>My JSON deserializing code presented previously works, but when an error occurs, most likely because the JSON doesn't represent the objects you expect it to, we're a bit lost: we get a terse error message and our program aborts, because Data.Generics tend to call error when it encounters a problem, and our own calls from Maybe to Just may fail. So we need to build a way to report errors without crashing. Now, &lt;a href="http://www.randomhacks.net/articles/2007/03/10/haskell-8-ways-to-report-errors"&gt;famously&lt;/a&gt;, there are several ways to report errors, and for a start I'll work with &lt;a href="http://www.haskell.org/ghc/docs/latest/html/libraries/base/Data-Either.html"&gt;Either&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;First, we create a error type that can help us represent both JSON parsing error and deserialization errors:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;data JSOND13NError=JSONError ParseError&lt;br /&gt;  | D13NError String String&lt;br /&gt;  deriving Show&lt;/pre&gt;&lt;br /&gt;  &lt;br /&gt;The two parameters in D13NError are the error message and the path in the JSON object where the error occured. They will be carried in the Either monad in a tuple of Strings&lt;br /&gt;&lt;br /&gt;So parsing can either throw a JSONError or try to deserialize:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;jsonStringToObj :: forall a. Data a =&gt; String -&gt; Either JSOND13NError a&lt;br /&gt;jsonStringToObj s= case parse JSON.json "JSON.parse" s of &lt;br /&gt; Left err-&gt;Left (JSONError err)&lt;br /&gt; Right js-&gt;case (jsonToObj js "/") of&lt;br /&gt;  Left (s,path) -&gt; Left (D13NError s path)&lt;br /&gt;  Right o-&gt; Right o&lt;/pre&gt;&lt;br /&gt;  &lt;br /&gt;The path starts at "/" for the deserialization&lt;br /&gt;&lt;br /&gt;To work with Either we need a couple of helper function, one to translate the Maybe values we get from cast to Either:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;toEither :: String -&gt; Maybe a -&gt; String -&gt; Either (String,String) a&lt;br /&gt;toEither s Nothing path=Left (s,path)&lt;br /&gt;toEither _ (Just a) _=Right a&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;And then the monad declaration for Either(message,path):&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;instance Monad (Either (String,String)) where&lt;br /&gt; return a=Right a&lt;br /&gt; fail s=Left (s,"/")&lt;br /&gt; Right a &gt;&gt;= f2 =f2 a&lt;br /&gt; Left s &gt;&gt;= f2 =Left s &lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;With this, our main function becomes:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;jsonToObj :: forall a. Data a =&gt; JSON.Value -&gt; String -&gt; Either (String,String) a&lt;br /&gt;jsonToObj (JSON.String s) path=toEither "Not a String" (cast s) path&lt;br /&gt;jsonToObj (JSON.Bool b) path=toEither "Not a Bool" (cast b) path&lt;br /&gt;jsonToObj x path=do&lt;br /&gt; (values,cons)&lt;-case x of&lt;br /&gt;   JSON.Object m -&gt; fieldJSONValues m myDataType path&lt;br /&gt;   JSON.Number fl -&gt; Right ([],if isPrefixOf "Prelude.Int" (dataTypeName myDataType)&lt;br /&gt;    then mkIntConstr myDataType (round fl)&lt;br /&gt;    else mkFloatConstr myDataType fl)&lt;br /&gt;   JSON.Array [] -&gt; Right ([],indexConstr myDataType 1)&lt;br /&gt;   JSON.Array (x:xs) -&gt; Right ([(x,path),((JSON.Array xs),path)],indexConstr myDataType 2)&lt;br /&gt; let StateT f=fromConstrM (StateT (\((x,path):xs) -&gt; do&lt;br /&gt;   r&lt;-jsonToObj x path&lt;br /&gt;   return (r,xs)&lt;br /&gt;   )) cons&lt;br /&gt; r&lt;- f values&lt;br /&gt; return (fst r)&lt;br /&gt; where&lt;br /&gt;  getArg :: a' -&gt; a'&lt;br /&gt;  getArg = undefined&lt;br /&gt;  getType :: a&lt;br /&gt;  getType = undefined&lt;br /&gt;  myDataType = dataTypeOf (getArg getType)&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;We use a StateT monad transformer to wrap our Either monad in the State. I'm not sure I understand 100% of how monad transformers actually work, but it works!&lt;br /&gt;&lt;br /&gt;And the fieldJSONValues handles a few error conditions, along with building the path where we're at, by adding after the current path the name of each field in turn&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;fieldJSONValues :: (M.Map String JSON.Value) -&gt; DataType -&gt; String -&gt; Either (String,String) ([(JSON.Value,String)],Constr)&lt;br /&gt;fieldJSONValues m dt path | isAlgType dt=&lt;br /&gt; if idx&gt;(maxConstrIndex dt)&lt;br /&gt;  then Left ((printf "Constructor index %d too big" idx),path)&lt;br /&gt;  else &lt;br /&gt;   if null fn &lt;br /&gt;    then Right ((map (\x-&gt;(fromJust $ M.lookup (show x) m',path++(show x)++"/")) (sort $ map (\x-&gt;((read x)::Int)) (M.keys m'))),c)&lt;br /&gt;    else  &lt;br /&gt;     let vals=map (\(x,y)-&gt;(fromJust x,y)) (filter (\(x,y)-&gt;isJust x) (map (\x-&gt;((M.lookup x m'),path++x++"/")) fn))&lt;br /&gt;     in if (length vals) &lt; (length fn)&lt;br /&gt;      then Left ("Not enough fields",path)&lt;br /&gt;      else Right (vals,c)&lt;br /&gt; where &lt;br /&gt;  idx=case M.lookup constrIndexField m of&lt;br /&gt;   Just (JSON.Number f)-&gt;truncate f&lt;br /&gt;   _ -&gt; 1&lt;br /&gt;  m'=M.delete constrIndexField m&lt;br /&gt;  c=indexConstr dt idx &lt;br /&gt;  fn=constrFields c&lt;br /&gt;fieldJSONValues m dt path | otherwise =Left ("Not an algebraic type",path)&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Once I had the previous code working, using a different monad and adding error handling was easy. I suppose I could further abstract and try not to hard code the Either monad in it but use any type of Monad or MonadError, but this gives me what I want: no program crash and the ability to recover from errors!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/37404288-1123342167001103987?l=jpmoresmau.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jpmoresmau.blogspot.com/feeds/1123342167001103987/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=37404288&amp;postID=1123342167001103987' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/37404288/posts/default/1123342167001103987'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/37404288/posts/default/1123342167001103987'/><link rel='alternate' type='text/html' href='http://jpmoresmau.blogspot.com/2008/07/handling-errors-in-json-to-haskell.html' title='Handling errors in JSON to Haskell deserialization'/><author><name>JP Moresmau</name><uri>http://www.blogger.com/profile/09964251063221757176</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='26' height='32' src='http://4.bp.blogspot.com/_SFBL69b3jRQ/TIUvCsYa5EI/AAAAAAAAACw/4H33zrk1nAI/S220/shades.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-37404288.post-6056806411650000350</id><published>2008-06-27T11:25:00.002+02:00</published><updated>2008-06-27T11:32:28.716+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Functional Programming'/><category scheme='http://www.blogger.com/atom/ns#' term='JSON'/><category scheme='http://www.blogger.com/atom/ns#' term='generics'/><category scheme='http://www.blogger.com/atom/ns#' term='Haskell'/><title type='text'>Deserializing JSON to Haskell Data objects</title><content type='html'>Since last week I found a few other posts and libraries on the subject of JSON serialization and deserialization: &lt;a href="http://hackage.haskell.org/cgi-bin/hackage-scripts/package/RJson"&gt;here&lt;/a&gt; and &lt;a href="http://lingnerd.blogspot.com/2007/12/pushing-haskells-type-system-to-limits.html"&gt;here&lt;/a&gt; for example. Nonetheless I've continued on my own path, since the best way of learning is doing. It took me a while to figure out how to reconstruct a Haskell object, and I've only got some limited functionnality to work, but it works. I looked into the source code for &lt;a href="http://www.haskell.org/ghc/docs/latest/html/libraries/base/src/Data-Generics-Text.html#gread"&gt;gread&lt;/a&gt; for clues, I have to say.&lt;br /&gt;&lt;br /&gt;So what we want is simple enough:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;jsonToObj :: forall a. Data a =&gt; JSON.Value -&gt; a&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Given a JSON value we want an haskell object, and hopefully the type will match... OK, I'm a bit terse on the error handling side of things at the moment!&lt;br /&gt;(Note: for the code to work you need to import: Control.Monad.State, Data.Generics, Data.List, qualified Data.Map as M, Data.Maybe)&lt;br /&gt;&lt;br /&gt;It's simple enough for Strings and Bools:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;jsonToObj (JSON.String s)=fromJust $ cast s&lt;br /&gt;jsonToObj (JSON.Bool b)=fromJust $ cast b&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Of course, if you expected a Foo and parse a JSON.String, this will fail(The cast return a Maybe). You have to cast since the signature doesn't force Strings or Bools, only Data.&lt;br /&gt;&lt;br /&gt;For other types of objects (including numbers, because cast doesn't perform number conversion I found) it's a bit more complicated. Basically we have to figure out the type we want, find a constructor to build an instance of that type, and pass to that constructors proper values from the JSON object.&lt;br /&gt;To find the type we want, I use funny code find in gread:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;myDataType = dataTypeOf (getArg getType)&lt;br /&gt;getArg :: a' -&gt; a'&lt;br /&gt;getArg = undefined&lt;br /&gt;getType :: a&lt;br /&gt;getType = undefined&lt;/pre&gt;&lt;br /&gt;  &lt;br /&gt;This create a dummy function returning my type, and a dummy function returning what it gets as parameter. They don't need to be implemented, the compiler only cares about the type.&lt;br /&gt;&lt;br /&gt;The meat of the function, that decides what constructor to invoke and what data to useas constructor parameter is a bit more involved:&lt;br /&gt;&lt;pre&gt;(values,cons)=case x of&lt;br /&gt; JSON.Object m -&gt; let&lt;br /&gt;  c=indexConstr myDataType 1&lt;br /&gt;  in ((map (\x-&gt;fromJust $ M.lookup x m) (constrFields c)),c)&lt;br /&gt; JSON.Number fl -&gt; ([],if isPrefixOf "Prelude.Int" (dataTypeName myDataType)&lt;br /&gt;  then mkIntConstr myDataType (round fl)&lt;br /&gt;  else mkFloatConstr myDataType fl)&lt;br /&gt; JSON.Array [] -&gt; ([],indexConstr myDataType 1)&lt;br /&gt; JSON.Array (x:xs) -&gt; ([x,(JSON.Array xs)],indexConstr myDataType 2)&lt;/pre&gt;&lt;br /&gt;   &lt;br /&gt;This snippet calculates the objects to iterator over and the constructor index to use. There's a bit a hand waving there: for objects we will take the first construtor we defined (I'll implement multiple constructor support later), and the JSON values it contains in the map. We just ensure we get the values in the order the fields are defined (given by the constrFields function). For number we use the int constructor if our result type looks like an int, otherwise we use the float constructor. There is probably a better way to construct a number from a Double, but I still need to find it. For the moment we look if the type name starts with "Prelude.Int", which is arguably not very Haskelly. For Arrays, we need to recreate the (head,rest) tuple that gave me trouble when serializing, so we deal first with the head of the list, and put the rest afterwards. The empty list is the first constructor, a non empty the second.&lt;br /&gt;&lt;br /&gt;Then to actually create the object we pass the values inside a &lt;a href="http://www.haskell.org/ghc/docs/latest/html/libraries/mtl/Control-Monad-State-Lazy.html"&gt;State monad&lt;/a&gt;:&lt;br /&gt;&lt;pre&gt;State f=(fromConstrM (State (\(x:xs) -&gt; (jsonToObj x,xs))) cons)&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;For the list of values we convert the head from json and keep the rest as state. This simple line was the result of intense thinking, I implemented my own State monad first to really understand what I needed to do and then figured out that the State monad did the exact same thing. The final working code is always shorter that all the previous failed attempts!&lt;br /&gt;We then only need to call the State function with the values we calculated earlier, and that give us our full code:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;jsonToObj x=&lt;br /&gt; fst $ f values&lt;br /&gt; where&lt;br /&gt;  getArg :: a' -&gt; a'&lt;br /&gt;  getArg = undefined&lt;br /&gt;  getType :: a&lt;br /&gt;  getType = undefined&lt;br /&gt;  myDataType = dataTypeOf (getArg getType)&lt;br /&gt;  (values,cons)=case x of&lt;br /&gt;   JSON.Object m -&gt; let&lt;br /&gt;    c=indexConstr myDataType 1&lt;br /&gt;    in ((map (\x-&gt;fromJust $ M.lookup x m) (constrFields c)),c)&lt;br /&gt;   JSON.Number fl -&gt; ([],if isPrefixOf "Prelude.Int" (dataTypeName myDataType)&lt;br /&gt;    then mkIntConstr myDataType (round fl)&lt;br /&gt;    else mkFloatConstr myDataType fl)&lt;br /&gt;   JSON.Array [] -&gt; ([],indexConstr myDataType 1)&lt;br /&gt;   JSON.Array (x:xs) -&gt; ([x,(JSON.Array xs)],indexConstr myDataType 2)&lt;br /&gt;  State f=(fromConstrM (State (\(x:xs) -&gt; (jsonToObj x,xs))) cons)&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/37404288-6056806411650000350?l=jpmoresmau.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jpmoresmau.blogspot.com/feeds/6056806411650000350/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=37404288&amp;postID=6056806411650000350' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/37404288/posts/default/6056806411650000350'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/37404288/posts/default/6056806411650000350'/><link rel='alternate' type='text/html' href='http://jpmoresmau.blogspot.com/2008/06/deserializing-json-to-haskell-data.html' title='Deserializing JSON to Haskell Data objects'/><author><name>JP Moresmau</name><uri>http://www.blogger.com/profile/09964251063221757176</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='26' height='32' src='http://4.bp.blogspot.com/_SFBL69b3jRQ/TIUvCsYa5EI/AAAAAAAAACw/4H33zrk1nAI/S220/shades.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-37404288.post-6656498439532415746</id><published>2008-06-20T14:21:00.002+02:00</published><updated>2008-06-20T14:31:19.597+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='JSON'/><category scheme='http://www.blogger.com/atom/ns#' term='generics'/><category scheme='http://www.blogger.com/atom/ns#' term='Haskell'/><title type='text'>Serializing Haskell objects to JSON</title><content type='html'>I'm trying to do some simple serialization of Haskell objects to save some state to disk. After tearing some of my hair out debugging parse errors due to silly code I'd written in Read instances declarations, I've decided to use another approach. I'm going to save objects as JSON, since I've already used that &lt;a href="http://www.tom.sfc.keio.ac.jp/%7Esakai/d/data/200604/JSON.hs"&gt;JSON library&lt;/a&gt;.&lt;br /&gt;The first task is to write generic code that can serialize a Data instance to JSON. This has probably been done somewhere else, but I need to learn, right? So I took a deep breath and dived into &lt;a href="http://www.haskell.org/ghc/docs/latest/html/libraries/base/Data-Generics.html"&gt;Data.Generics&lt;/a&gt;.&lt;br /&gt;I quickly rounded up the issues I would face. Most notably, Strings and lists are accessed without any syntaxic sugar, so to speak: Strings are lists of Char, and lists are made of two fields, the head and the rest. Of course, you say, but from that I need to regenerate String and lists of JSON Value objects.&lt;br /&gt;So, to start, how to recognize Strings to treat them differently than other algrebraic types:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;isString :: Data a =&gt; a -&gt; Bool&lt;br /&gt;isString a = (typeOf a) == (typeOf "")&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;There's probably better ways to do that, just tell me (-:&lt;br /&gt;&lt;br /&gt;Lists (that are not strings) can be recognized with abstract representations of constructors, which are equals regardless of the actual type of elements in the list&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;isList :: Data a =&gt; a -&gt; Bool&lt;br /&gt;isList a&lt;br /&gt;   | isString a = False&lt;br /&gt;   | otherwise  = (typeRepTyCon (typeOf a)) == (typeRepTyCon $ typeOf ([]::[Int]))&lt;/pre&gt;&lt;br /&gt; &lt;br /&gt;Now, transforming a list of the form (head,rest) to [head1,head2...]&lt;br /&gt; &lt;br /&gt;&lt;pre&gt;jsonList :: Data a =&gt; a -&gt; [JSON.Value]&lt;br /&gt;jsonList l=&lt;br /&gt;   concat $ gmapQ f l&lt;br /&gt;   where f b&lt;br /&gt;       | (isList b)= jsonList b&lt;br /&gt;       | otherwise = [objToJson b]&lt;/pre&gt;&lt;br /&gt;     &lt;br /&gt;For each element (the actual number depends on whether we're the empty list or not) we either reapply the same method, if it's the inner list or we simply transform to JSON&lt;br /&gt;&lt;br /&gt;And then the actual method on objects:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;objToJson :: Data a =&gt; a -&gt; JSON.Value&lt;br /&gt;objToJson o | isString o=JSON.String (fromJust $ ((cast o)::(Maybe String)))&lt;br /&gt;objToJson o | isList o=JSON.Array (jsonList o)&lt;br /&gt;objToJson o | otherwise=&lt;br /&gt;   let&lt;br /&gt;       c=toConstr o&lt;br /&gt;   in&lt;br /&gt;       case (constrRep c) of&lt;br /&gt;           AlgConstr _-&gt; JSON.Object (Data.Map.fromList(zip (constrFields c) (gmapQ objToJson o)))&lt;br /&gt;           StringConstr s -&gt; JSON.String s&lt;br /&gt;           FloatConstr f -&gt; JSON.Number f&lt;br /&gt;           IntConstr i -&gt; JSON.Number (fromIntegral i)&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;We first handle Strings, then list, then general objects using constrRep to distinguish between algebraic types that create JSON objects with the proper field names (using constrFields) and other types for JSON primitives.&lt;br /&gt;&lt;br /&gt;And that's it for the serialization! The Generics package is not that hard to use but you have to look up examples to figure out how actually use the functions like gmapQ and such...&lt;br /&gt;&lt;br /&gt;Now, I have to work on the opposite process: given a type and JSON data, reconstruct the objects... More Haskell fun!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/37404288-6656498439532415746?l=jpmoresmau.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jpmoresmau.blogspot.com/feeds/6656498439532415746/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=37404288&amp;postID=6656498439532415746' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/37404288/posts/default/6656498439532415746'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/37404288/posts/default/6656498439532415746'/><link rel='alternate' type='text/html' href='http://jpmoresmau.blogspot.com/2008/06/serializing-haskell-objects-to-json.html' title='Serializing Haskell objects to JSON'/><author><name>JP Moresmau</name><uri>http://www.blogger.com/profile/09964251063221757176</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='26' height='32' src='http://4.bp.blogspot.com/_SFBL69b3jRQ/TIUvCsYa5EI/AAAAAAAAACw/4H33zrk1nAI/S220/shades.jpg'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-37404288.post-752279524637732979</id><published>2008-04-11T16:00:00.002+02:00</published><updated>2008-04-11T16:08:22.243+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Functional Programming'/><category scheme='http://www.blogger.com/atom/ns#' term='Haskell'/><title type='text'>The unintentional infinite list</title><content type='html'>&lt;span style="font-size:100%;"&gt;The other day I was happily hacking away at some Haskell code. Same thing as always: think hard at about how to represent my problem in Haskell, then type the code quickly enough. Then launch my HUnit test. Tests doesn't return, just seem to be looping for ever!! Uh oh.&lt;br /&gt;So I check my code, all the foldr and foldl and such, to make sure nowhere I create an infinite sequence. Nothing. So I took a deep breath and started the ghci debugger. I'm used to graphical debugger (like Java in Eclipse) but hey I managed to pretty quickly locate the offending function. Only a typo that couldn't be caught by the compiler. Since it's not the first time this has happened to me, here it is:&lt;br /&gt;I tend to not be too comfortable with big one liner functions, so I revert often to several lines after a let instruction to cleanly separate each step of the computation. So when I repeatedly change some structure I tend to get:&lt;br /&gt;&lt;/span&gt;&lt;pre&gt;&lt;span style="font-size:100%;"&gt;&lt;br /&gt;fn a =&lt;br /&gt;   let&lt;br /&gt;       a1=fn1 a&lt;br /&gt;       a2=fn2 a1&lt;br /&gt;   in fn3 a2&lt;br /&gt;&lt;/span&gt;&lt;/pre&gt;&lt;span style="font-size:100%;"&gt;&lt;br /&gt;and the typo there was a line like:&lt;br /&gt;&lt;/span&gt;&lt;pre&gt;&lt;span style="font-size:100%;"&gt;    a2 = fn2 a2&lt;/span&gt;&lt;/pre&gt;&lt;span style="font-size:100%;"&gt;&lt;br /&gt;&lt;br /&gt;So I had typed in a2 instead of a1, and the compiler was perfectly happy, I wanted to create an infinite list, right? Er... That wasn't exactly my intention.&lt;br /&gt;So I fixed the typo. Then ran my test. Which passed. Of course.&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/37404288-752279524637732979?l=jpmoresmau.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jpmoresmau.blogspot.com/feeds/752279524637732979/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=37404288&amp;postID=752279524637732979' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/37404288/posts/default/752279524637732979'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/37404288/posts/default/752279524637732979'/><link rel='alternate' type='text/html' href='http://jpmoresmau.blogspot.com/2008/04/unintentional-infinite-list.html' title='The unintentional infinite list'/><author><name>JP Moresmau</name><uri>http://www.blogger.com/profile/09964251063221757176</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='26' height='32' src='http://4.bp.blogspot.com/_SFBL69b3jRQ/TIUvCsYa5EI/AAAAAAAAACw/4H33zrk1nAI/S220/shades.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-37404288.post-4937763243978487397</id><published>2008-04-01T16:10:00.005+02:00</published><updated>2008-04-01T16:21:30.693+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Java'/><category scheme='http://www.blogger.com/atom/ns#' term='Compilation'/><category scheme='http://www.blogger.com/atom/ns#' term='Dynamic languages'/><category scheme='http://www.blogger.com/atom/ns#' term='Haskell'/><title type='text'>Me and my compiler</title><content type='html'>Pfiuu, long time no post, between my day time work, playing with Haskell and Lispy things (cool sutff like &lt;a href="http://clojure.sourceforge.net/"&gt;Clojure&lt;/a&gt;) and my extra-programming activities (yes, yes)...&lt;br /&gt;I was just thinking about dynamically vs statically typed languages, since there is a lot of discussion about that on the web these days. For example, &lt;a href="http://www.artima.com/weblogs/viewpost.jsp?thread=227806"&gt;this article&lt;/a&gt; talks about refactoring in both static and dynamic languages. Well, I'm not a huge fan of all the refactoring utilities Eclipse give me, but there's one feature I use a lot: you know, when I change something, like the return type or the arguments of a method, my IDE helpfully adds little red crosses on all the source files that won't compile any more. So then I go through them and adapt the code.&lt;br /&gt;Of course in a dynamically typed language I wouldn't get that, but since everybody has 100% code path coverage in their unit tests, it's just deferring the red cross marking a bit lower than the chain, right? Well, at work it takes 30 minutes to build our whole software from SVN (and only a few seconds to rebuild one individual module from inside Eclipse), and several hours to unit test everything (and have we got 100% test coverage?), so... Methinks I'll stick with something that can check that my types are coherent for me when I work on big projects...&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/37404288-4937763243978487397?l=jpmoresmau.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jpmoresmau.blogspot.com/feeds/4937763243978487397/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=37404288&amp;postID=4937763243978487397' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/37404288/posts/default/4937763243978487397'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/37404288/posts/default/4937763243978487397'/><link rel='alternate' type='text/html' href='http://jpmoresmau.blogspot.com/2008/04/me-and-my-compiler.html' title='Me and my compiler'/><author><name>JP Moresmau</name><uri>http://www.blogger.com/profile/09964251063221757176</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='26' height='32' src='http://4.bp.blogspot.com/_SFBL69b3jRQ/TIUvCsYa5EI/AAAAAAAAACw/4H33zrk1nAI/S220/shades.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-37404288.post-2078186858481727199</id><published>2008-01-18T16:18:00.000+01:00</published><updated>2008-01-18T16:25:44.299+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='generics'/><category scheme='http://www.blogger.com/atom/ns#' term='Haskell'/><title type='text'>Scraping my boilerplate: Generics instead of Records</title><content type='html'>I was talking&lt;a href="http://jpmoresmau.blogspot.com/2008/01/nested-records-headaches-in-haskell.html"&gt; last week&lt;/a&gt; about my trouble writing simple code to access and update record field in Haskell. While talking with&lt;a href="http://www.blogger.com/profile/04138857652921543796"&gt; justin&lt;/a&gt; about it, he suggested using parameter type for record object, so that the compiler would check that an update method would actually take as parameters the proper rating and the corresponding update function. That was cool enough, and that got me into the &lt;a href="http://www.cs.vu.nl/boilerplate/"&gt;"Scrap your boilerplate" papers&lt;/a&gt; and &lt;a href="http://www.haskell.org/ghc/docs/latest/html/libraries/base/src/Data-Generics.html"&gt;Data.Generics&lt;/a&gt; modules. What I have now, using generics programming, is fairly simple and I think I'm getting closer to what Haskell code should be like.&lt;br /&gt;First, Ratings: a Rating has three int values: the current level, normal level, and the experience points. What I do now is that each value is actually typed, and the Rating only holds a list of them:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;data RatingScoreType=Normal |&lt;br /&gt;    Current |&lt;/span&gt;&lt;br /&gt;    Experience&lt;/span&gt;&lt;br /&gt;    deriving (Show,Read,Enum,Eq,Typeable,Data)&lt;br /&gt;&lt;br /&gt;data RatingScore=RatingScore RatingScoreType Int&lt;br /&gt;    deriving (Show,Read,Typeable,Data)&lt;br /&gt;data Rating=Rating [RatingScore]&lt;br /&gt;    deriving (Typeable,Data)&lt;br /&gt;  &lt;/pre&gt;&lt;br /&gt;With that I can add an update method that only changes a RatingScore if the type match with the type provided:&lt;br /&gt;   &lt;br /&gt;&lt;pre&gt;addRS :: RatingScoreType -&gt; Int -&gt; RatingScore -&gt; RatingScore&lt;br /&gt;addRS  t2 b rs@(RatingScore t1 a)&lt;br /&gt;    | t1==t2=RatingScore t1 (a+b)&lt;br /&gt;    | otherwise=rs&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;And a method that tells me if a score match the given type&lt;br /&gt;   &lt;br /&gt;&lt;pre&gt;getRS :: RatingScoreType -&gt; RatingScore -&gt; Bool&lt;br /&gt;getRS t2 rs@(RatingScore t1 a) &lt;br /&gt;    | t1==t2=True&lt;br /&gt;    | otherwise=False&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;(note that addRS can be rewritten using getRS but we don't gain anything in code size)&lt;br /&gt;&lt;br /&gt;I can then use Data.Generics functions to provide generic update and get functions:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;addR :: Data a =&gt; RatingScoreType -&gt; Int -&gt; a -&gt; a&lt;br /&gt;addR rst i=everywhere (mkT (addRS rst i))&lt;br /&gt;&lt;br /&gt;getR :: Data a =&gt; RatingScoreType -&gt; a -&gt; Int&lt;br /&gt;getR rst a=&lt;br /&gt;    let (RatingScore t1 b)= head $ listify (getRS rst) a&lt;br /&gt;    in b&lt;/pre&gt;&lt;br /&gt;   &lt;br /&gt;(There are probably other and maybe better way of writing these, but hey, the documentation is not very rich in examples...)&lt;br /&gt;&lt;br /&gt;The level above Ratings are Characteristics: a character holds an array of CharacteristicRating:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;data CharacteristicRating = CharacteristicRating Characteristic Rating&lt;br /&gt;    deriving (Show,Read,Typeable,Data)&lt;/pre&gt;&lt;br /&gt;   &lt;br /&gt;Where Characteristic is again an Enum of all possible characteristics.&lt;br /&gt;&lt;br /&gt;I define the similar 4 functions as above, except they filter on Characteristic first and RatingScoreType second:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;addC :: Characteristic -&gt; RatingScoreType -&gt; Int -&gt; CharacteristicRating -&gt; CharacteristicRating&lt;br /&gt;addC c2 rst i cr@(CharacteristicRating c1 r) &lt;br /&gt;    | c1==c2=everywhere (mkT (addRS rst i)) cr&lt;br /&gt;    | otherwise=cr&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;getC :: Characteristic -&gt; RatingScoreType -&gt; CharacteristicRating -&gt; Bool&lt;br /&gt;getC c2 rst cr@(CharacteristicRating c1 r) &lt;br /&gt;    | c1==c2=True&lt;br /&gt;    | otherwise=False&lt;br /&gt;&lt;br /&gt;addCharacteristic :: Data a =&gt; Characteristic -&gt; RatingScoreType -&gt; Int -&gt; a -&gt; a&lt;br /&gt;addCharacteristic c rst i a = everywhere (mkT (addC c rst i)) a&lt;br /&gt;&lt;br /&gt;getCharacteristic :: Data a =&gt; Characteristic -&gt; RatingScoreType -&gt; a -&gt; Int&lt;br /&gt;getCharacteristic c rst a = &lt;br /&gt;    let cr=head $ listify (getC c rst) a&lt;br /&gt;    in getR rst cr&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;This is pretty cool: if I have a Character c:&lt;br /&gt;&lt;pre&gt;getCharacteristic Strength Current c&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Gives me the current strength! And a function can take a Data instance (a Character or anything else) and a Characteristic and do both testing and changing value in perfect safety!&lt;br /&gt;&lt;br /&gt;Now I'm only just starting playing the Data.Generics, and more generally with Haskell program design, but this is cool. My RPG is not progressing fast, but the main game here is actually building it, not playing it!!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/37404288-2078186858481727199?l=jpmoresmau.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jpmoresmau.blogspot.com/feeds/2078186858481727199/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=37404288&amp;postID=2078186858481727199' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/37404288/posts/default/2078186858481727199'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/37404288/posts/default/2078186858481727199'/><link rel='alternate' type='text/html' href='http://jpmoresmau.blogspot.com/2008/01/scraping-my-boilerplate-generics.html' title='Scraping my boilerplate: Generics instead of Records'/><author><name>JP Moresmau</name><uri>http://www.blogger.com/profile/09964251063221757176</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='26' height='32' src='http://4.bp.blogspot.com/_SFBL69b3jRQ/TIUvCsYa5EI/AAAAAAAAACw/4H33zrk1nAI/S220/shades.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-37404288.post-9118957270435758988</id><published>2008-01-11T13:33:00.000+01:00</published><updated>2008-01-11T13:36:58.623+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Software design'/><category scheme='http://www.blogger.com/atom/ns#' term='Haskell'/><title type='text'>Nested records headaches in Haskell</title><content type='html'>I'm fighting a bit with Haskell records and named fields. &lt;a href="http://bloggablea.wordpress.com/2007/04/24/haskell-records-considered-grungy/"&gt;This post&lt;/a&gt; has some valid remarks, but no real solutions. The main problem I have is managing elegantly nested records:&lt;br /&gt;In my (embryonic) Haskell RPG game, a character is defined as a data type with several named fields (name, gender, traits). Traits is a collection of all characteristics (Strength, Dexterity, etc.). Each trait is itself a record with three values (normal level, current level, experience points). When an action is performed, not only we look at a rating value, we also update the rating experience as a result. So I want a function that takes a character, the name of a characteristic, and can update the proper characteristic rating.&lt;br /&gt;With records&lt;br /&gt;&lt;span style="font-family: courier new;"&gt;Traits { strength::Rating...} &lt;/span&gt;&lt;br /&gt;I get a lookup function: a function strength that I can use to get the current value, so I can have a function like&lt;br /&gt;&lt;span style="font-family: courier new;"&gt;testTrait :: Character -&gt; (Traits -&gt; Rating) -&gt; ...&lt;/span&gt;&lt;br /&gt;Where ... is whatever result the function returns (something like IO(Character,TestResult). But if testTrait needs to modify the record, I don't have a dynamic function to do it! And even if my code could hard code that "strength" is the trait I need, then the update mechanism is singularly cumbersome, since:&lt;br /&gt;&lt;span style="font-family: courier new;"&gt;let c1=c{traits{strength{experience=1}}}&lt;/span&gt;&lt;br /&gt;Doesn't compile (c is a character, I want to set experience of strength to 1). And if I want to modify the value (like do a +1 instead of setting to 1), then I need to unstack everything and rebuild it. Argh! Surely there is a better way?&lt;br /&gt;&lt;br /&gt;The solution I have for the moment is that Traits contains only a list of Rating objects. Then I've defined an Enum with a constructor for each characteristic:&lt;br /&gt;&lt;span style="font-family: courier new;"&gt;data Characteristic = Strength | ...&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt;    deriving (Show,Read,Eq,Enum,Bounded)&lt;/span&gt;&lt;br /&gt;and I can have a method that combines fromEnum and !! to retrieve the right value. I can also have a little function that let me update a precise element in a list. But of course the type system does not guarantee me that every Character will have the right amount of Rating objects in the array!&lt;br /&gt;&lt;br /&gt;It may be that my brain has been totally formatted by years of Java (in Java I could just pass the Rating object and it would get modified in place of course), but I just don't know what structure would give me total safety (enforcing that every character has the proper data) with no boilerplate code and no duplication. (I know I can define helper methods to do all of that, but I though Haskell would let me cut the amount of purely technical code needed and concentrate on the business).&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/37404288-9118957270435758988?l=jpmoresmau.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jpmoresmau.blogspot.com/feeds/9118957270435758988/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=37404288&amp;postID=9118957270435758988' title='4 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/37404288/posts/default/9118957270435758988'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/37404288/posts/default/9118957270435758988'/><link rel='alternate' type='text/html' href='http://jpmoresmau.blogspot.com/2008/01/nested-records-headaches-in-haskell.html' title='Nested records headaches in Haskell'/><author><name>JP Moresmau</name><uri>http://www.blogger.com/profile/09964251063221757176</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='26' height='32' src='http://4.bp.blogspot.com/_SFBL69b3jRQ/TIUvCsYa5EI/AAAAAAAAACw/4H33zrk1nAI/S220/shades.jpg'/></author><thr:total>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-37404288.post-7192609061555501767</id><published>2008-01-11T12:43:00.000+01:00</published><updated>2008-01-11T12:50:20.581+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Java'/><category scheme='http://www.blogger.com/atom/ns#' term='Haskell'/><title type='text'>Haskell syntax is not Java syntax; good or bad?</title><content type='html'>In &lt;a href="http://www.jroller.com/RickHigh/entry/thanks_zed_btw_syntax_matters"&gt;this blog&lt;/a&gt;, the author expresses the opinion that an important part of a language popularity: Java was successful because it looked familiar to C++ developers, and similarly new languages should use Java syntax. This struck a chord: after all, I have started writing a pure functional language using Java syntax. I thought that having a similar syntax would help grasping the language better. But now I wonder. Not only do C++ and Java share a similar syntax, they also share some concepts (objects, etc...). If a language is intrinsically different (like a pure functional language with monads, say), then having a different syntax tells you straight away: warning! This is different, so not only you must learn a new syntax, but you must also learn a new way of programming.&lt;br /&gt;So maybe having Haskell using a totally different syntax is A Good Thing. And it gives me a nice excuse to stop trying to create my own little language that looks a bit like Java but doesn't act like Java and concentrate on writing Haskell code.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/37404288-7192609061555501767?l=jpmoresmau.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jpmoresmau.blogspot.com/feeds/7192609061555501767/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=37404288&amp;postID=7192609061555501767' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/37404288/posts/default/7192609061555501767'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/37404288/posts/default/7192609061555501767'/><link rel='alternate' type='text/html' href='http://jpmoresmau.blogspot.com/2008/01/haskell-syntax-is-not-java-syntax-good.html' title='Haskell syntax is not Java syntax; good or bad?'/><author><name>JP Moresmau</name><uri>http://www.blogger.com/profile/09964251063221757176</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='26' height='32' src='http://4.bp.blogspot.com/_SFBL69b3jRQ/TIUvCsYa5EI/AAAAAAAAACw/4H33zrk1nAI/S220/shades.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-37404288.post-2836214013099133409</id><published>2007-12-21T08:37:00.000+01:00</published><updated>2007-12-21T08:53:06.391+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Scala'/><category scheme='http://www.blogger.com/atom/ns#' term='Functional Programming'/><category scheme='http://www.blogger.com/atom/ns#' term='Java'/><category scheme='http://www.blogger.com/atom/ns#' term='generics'/><category scheme='http://www.blogger.com/atom/ns#' term='Haskell'/><title type='text'>Java and higher order generics</title><content type='html'>&lt;span style="font-family:georgia;"&gt;Funny coincidence: yesterday in work I was trying to find a way to express something simple enough in Java: I want a method map that takes a generic collection and return a collection of the same type (that is, passing a List should return a List, passing a Set should return a Set) with a different generic type. In Java you can have:&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;public &amp;lt;T1,T2&gt; Collection&amp;lt;T2&gt; map(Collection&amp;lt;T1&gt; c,Mapper&amp;lt;T1,T2&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;&lt;br /&gt;&lt;span style="font-family:georgia;"&gt;Where Mapper is an interface defining the method T2 map(T1 o);&lt;br /&gt;There is no way I think in Java to express that if you pass a subclass of collection you get the same subclass back.&lt;br /&gt;&lt;br /&gt;I tried things like &lt;span style="font-family: courier new;"&gt;&amp;lt;T1,T2,C extends Collection,C1 extends C&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family: courier new;font-family:courier new;" &gt;&amp;lt;&lt;/span&gt;&lt;span style="font-family: courier new;font-family:courier new;" &gt;T1&gt;,C2 extends C&lt;/span&gt;&lt;span style="font-family: courier new;font-family:courier new;" &gt;&amp;lt;&lt;/span&gt;&lt;span style="font-family:courier new;"&gt;&lt;span style="font-family:courier new;"&gt;&lt;span style="font-family:georgia;"&gt;&lt;span style="font-family: courier new;"&gt;T2&gt;&lt;/span&gt; and other crazy things that my compiler didn't appreciate.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;You have to duplicate methods, and that's what we've done in work:&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family:courier new;"&gt;public &amp;lt;T1,T2&gt; List&amp;lt;T2&gt; map(List&amp;lt;T1&gt; c,Mapper&amp;lt;T1,T2&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="font-family:courier new;"&gt;public &amp;lt;T1,T2&gt; Set&amp;lt;T2&gt; map(Set&amp;lt;T1&gt; c,Mapper&amp;lt;T1,T2&gt;&lt;span style="font-family:georgia;"&gt;&lt;br /&gt;&lt;br /&gt;And of course a colleague needed a Vector because he was using an old library still using Vectors...&lt;br /&gt;And then today I found that blog post, that point to that &lt;a href="http://www.cs.kuleuven.be/%7Eadriaan/files/genericshk/tcpoly.pdf"&gt;PDF document&lt;/a&gt;. Apparently you can do this kind of things in Scala and Haskell... Do I need to convince my company to move to Scala?&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/37404288-2836214013099133409?l=jpmoresmau.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jpmoresmau.blogspot.com/feeds/2836214013099133409/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=37404288&amp;postID=2836214013099133409' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/37404288/posts/default/2836214013099133409'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/37404288/posts/default/2836214013099133409'/><link rel='alternate' type='text/html' href='http://jpmoresmau.blogspot.com/2007/12/java-and-higher-order-generics.html' title='Java and higher order generics'/><author><name>JP Moresmau</name><uri>http://www.blogger.com/profile/09964251063221757176</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='26' height='32' src='http://4.bp.blogspot.com/_SFBL69b3jRQ/TIUvCsYa5EI/AAAAAAAAACw/4H33zrk1nAI/S220/shades.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-37404288.post-7654521416299869173</id><published>2007-11-30T14:19:00.000+01:00</published><updated>2007-11-30T14:27:16.419+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Software design'/><category scheme='http://www.blogger.com/atom/ns#' term='Functional Programming'/><category scheme='http://www.blogger.com/atom/ns#' term='Haskell'/><title type='text'>Haskell design patterns are (probably) needed</title><content type='html'>I was reading that &lt;a href="http://notes-on-haskell.blogspot.com/2007/02/design-patterns-arent-revisited.html"&gt;post&lt;/a&gt;, and thinking: well when I start a Haskell project (for fun, yes, I don't use Haskell in work) I do wonder how best to design it. Yes I know about higher order functions, generics and such, but I don't think these low level constructs are enough to express, on their own, the design of the system as the design patterns from the GoF do.  I would love to see patterns on how to allow extensibility, separation of concerns and such in Haskell. Years of experience in Java mean that I see a lot of things in terms of objects, inheritance vs composition, interfaces, etc, and not all of that apply in Haskell. I see a lot of low level algorithms in Haskell, but few software design papers (papers like &lt;a href="http://haskell.org/papers/NSWC/jfp.ps"&gt;this one&lt;/a&gt; are useful, we need more of them).&lt;a href="http://notes-on-haskell.blogspot.com/2007/02/design-patterns-arent-revisited.html"&gt;&lt;br /&gt;&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/37404288-7654521416299869173?l=jpmoresmau.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jpmoresmau.blogspot.com/feeds/7654521416299869173/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=37404288&amp;postID=7654521416299869173' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/37404288/posts/default/7654521416299869173'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/37404288/posts/default/7654521416299869173'/><link rel='alternate' type='text/html' href='http://jpmoresmau.blogspot.com/2007/11/haskell-design-patterns-are-probably.html' title='Haskell design patterns are (probably) needed'/><author><name>JP Moresmau</name><uri>http://www.blogger.com/profile/09964251063221757176</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='26' height='32' src='http://4.bp.blogspot.com/_SFBL69b3jRQ/TIUvCsYa5EI/AAAAAAAAACw/4H33zrk1nAI/S220/shades.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-37404288.post-4000476321620492313</id><published>2007-11-26T08:30:00.000+01:00</published><updated>2007-11-26T08:32:03.316+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Functional Programming'/><category scheme='http://www.blogger.com/atom/ns#' term='Java'/><category scheme='http://www.blogger.com/atom/ns#' term='Haskell'/><title type='text'>Structure of a functional Java, er, method</title><content type='html'>A method in FLOJ (remember, the functional Java based language I'm toying with) has a simple structure:&lt;br /&gt;- a method definition 100% similar to a normal Java method: visibility generic return-type type parameters.&lt;br /&gt;There are no exceptions, of course, since exceptions are things Best Done in Monads, once I've figured out&lt;br /&gt;out I'll implement monads.&lt;br /&gt;- a series of assignments of the form x=e where x is a variable name, and e an expression&lt;br /&gt;- a return expression&lt;br /&gt;&lt;br /&gt;For example:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;public static String[] testMap(){&lt;br /&gt;   a=["toto","titi"];&lt;br /&gt;   a.map(String.toUpperCase);&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Since the return expression is always the last expression, there is no need for a return keyword, but it's accepted by the parser. In the exemple above, the method returns the list of String TOTO and TITI.&lt;br /&gt;Note also that the assignments do not allow nor require the type definition of the left hand side of the assignment. The type is inferred from the&lt;br /&gt;return type of the right hand side expression (in the exemple above, a is a list of String). It's not as powerful as the full blown Haskell type inference but at least it saves some typing.&lt;br /&gt;&lt;br /&gt;Of course, the generated Java code will add a sneaky final keyword to all the assignments, to enforce the fact that there's no variables in a functional language.&lt;br /&gt;&lt;br /&gt;All in all, that structure makes the code easy to read and to understand: the sequence of calculations and the final expression yielding the method result.&lt;br /&gt;&lt;br /&gt;I don't think my FLOJ language will ever be a full blown industrial-strength language, but I know that by implementing my own functional language I will learn a lot&lt;br /&gt;more about functional languages than by just using one. Just implementing method pointers, type inference, combinator parsers and such, I understand more the why and how of Haskell.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/37404288-4000476321620492313?l=jpmoresmau.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jpmoresmau.blogspot.com/feeds/4000476321620492313/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=37404288&amp;postID=4000476321620492313' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/37404288/posts/default/4000476321620492313'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/37404288/posts/default/4000476321620492313'/><link rel='alternate' type='text/html' href='http://jpmoresmau.blogspot.com/2007/11/structure-of-functional-java-er-method.html' title='Structure of a functional Java, er, method'/><author><name>JP Moresmau</name><uri>http://www.blogger.com/profile/09964251063221757176</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='26' height='32' src='http://4.bp.blogspot.com/_SFBL69b3jRQ/TIUvCsYa5EI/AAAAAAAAACw/4H33zrk1nAI/S220/shades.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-37404288.post-7242740203443442529</id><published>2007-10-26T12:21:00.000+02:00</published><updated>2007-10-26T12:28:16.248+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Object Oriented Programming'/><category scheme='http://www.blogger.com/atom/ns#' term='Functional Programming'/><category scheme='http://www.blogger.com/atom/ns#' term='Java'/><category scheme='http://www.blogger.com/atom/ns#' term='Haskell'/><title type='text'>A simple functional structure in Java</title><content type='html'>I have progressed a little bit in creating a functional language on top of Java, code name FLOJ (Functional Language On Java (-:). For the moment I'm only working on single files (I have a working parser), on the simple language constructs.&lt;br /&gt;It's really interesting, because looking at very simple things make you think in depth about some issues that you may not really consider in Java proper. For example, this is the definition of a very simple structure:&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;&lt;br /&gt;&lt;pre&gt;package fr.moresmau.jp.floj.samples;&lt;br /&gt;&lt;br /&gt;public class Simple(String data,int port){&lt;br /&gt;&lt;br /&gt;}&lt;/pre&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;So you can see that the package system is Java's and class definition are very similar. There are no constructor, so. Since null are not allowed (nulls are a huge source of bugs, I'll provide a Maybe object or something like that later),&lt;br /&gt;the structure must have all its data filled in. If you want different operations to be done, you just create static functions that take parameters and create what you need, no need for several constructors. So the list of fields is entered straight after the name of the class.&lt;br /&gt;Simple is a structure with a string and an int. It's easy enough to generate the constructor in Java:&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;&lt;br /&gt;&lt;pre&gt;package fr.moresmau.jp.floj.samples;&lt;br /&gt;&lt;br /&gt;public class Simple{&lt;br /&gt; public final String data;&lt;br /&gt; &lt;br /&gt; public final int port;&lt;br /&gt; &lt;br /&gt; public Simple(final String _data, final int _port){&lt;br /&gt;  if(_data==null){throw new NullPointerException("_data");}&lt;br /&gt;  this.data=_data;&lt;br /&gt;  this.port=_port;&lt;br /&gt; }&lt;br /&gt;... &lt;/pre&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;The fields are immutable of course, so we don't bother with a getXXX() method, we just expose the field.&lt;br /&gt;And you can then add setters that return a new object :&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;&lt;pre&gt;&lt;br /&gt;... public Simple setData(final String _data){&lt;br /&gt;  if(_data==null){throw new NullPointerException("_data");}&lt;br /&gt;  if (_data.equals(data)){return this;}&lt;br /&gt;  return new fr.moresmau.jp.floj.samples.Simple(_data,port);&lt;br /&gt; }&lt;br /&gt; &lt;br /&gt; public Simple setPort(final int _port){&lt;br /&gt;  if (_port==port){return this;}&lt;br /&gt;  return new fr.moresmau.jp.floj.samples.Simple(data,_port);&lt;br /&gt; }&lt;br /&gt;...&lt;/pre&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Note the null handling is not ideal, left for later. Note also we avoid superfluous creations if the data will not change.&lt;br /&gt;&lt;br /&gt;So far, so good.&lt;br /&gt;&lt;br /&gt;Then I decided to implement equals, so that equals is based on the data and not pointer equality:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;&lt;pre&gt;&lt;br /&gt;...&lt;br /&gt; public boolean equals(final java.lang.Object o){&lt;br /&gt;  if (this==o){return true;}&lt;br /&gt;  if (o instanceof fr.moresmau.jp.floj.samples.Simple){&lt;br /&gt;   fr.moresmau.jp.floj.samples.Simple co=(fr.moresmau.jp.floj.samples.Simple)o;&lt;br /&gt;   if (!this.data.equals(co.data)){return false;}&lt;br /&gt;   if (this.port!=co.port){return false;}&lt;br /&gt;   return true;&lt;br /&gt;  }&lt;br /&gt;  return false;&lt;br /&gt; }&lt;br /&gt;...&lt;/pre&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;And with this of course the problem of overloaded equals method raises its head. If I want to allow subclasses to add more fields, my equals method won't work for subclasses.&lt;br /&gt;If I check the exact class name in equals, subclasses that only add/overload methods will not be equals to superclasses.&lt;br /&gt;So what can I do? I haven't decided. I could forbid subclasses to define more data fields (that's I think what you have in Haskell: you inherit functions from your type classes but no data).&lt;br /&gt;I could also make the equals method final and not generate it for subclasses, but equality would then ignore the additional fields.&lt;br /&gt;Another option would be to check the class name in that equals method and generate the proper equals method for all subclasses, but that may cause problems if we then extends the FLOJ class by a Java Class (which will be possible since we generate Java code).&lt;br /&gt;But maybe it should be so, that a class is never equals to its subclasses? Returning equals between two instances that have the same data but different behavior (one instance has an overloaded method) is probably an error in the OO world...&lt;br /&gt;&lt;br /&gt;Anyway, creating your own language is fun, I'm learning a lot and maybe I'll even end up with something usable!! I'll keep you posted on my progress.&lt;/pre&gt;&lt;/pre&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/37404288-7242740203443442529?l=jpmoresmau.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jpmoresmau.blogspot.com/feeds/7242740203443442529/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=37404288&amp;postID=7242740203443442529' title='6 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/37404288/posts/default/7242740203443442529'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/37404288/posts/default/7242740203443442529'/><link rel='alternate' type='text/html' href='http://jpmoresmau.blogspot.com/2007/10/simple-functional-structure-in-java.html' title='A simple functional structure in Java'/><author><name>JP Moresmau</name><uri>http://www.blogger.com/profile/09964251063221757176</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='26' height='32' src='http://4.bp.blogspot.com/_SFBL69b3jRQ/TIUvCsYa5EI/AAAAAAAAACw/4H33zrk1nAI/S220/shades.jpg'/></author><thr:total>6</thr:total></entry><entry><id>tag:blogger.com,1999:blog-37404288.post-3004742437482912923</id><published>2007-10-11T10:13:00.003+02:00</published><updated>2008-10-16T08:31:45.217+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Java'/><category scheme='http://www.blogger.com/atom/ns#' term='Python'/><category scheme='http://www.blogger.com/atom/ns#' term='Concurrent Programming'/><title type='text'>Generator (with yield) in Java</title><content type='html'>For some reason I was thinking about &lt;a href="http://en.wikipedia.org/wiki/Generator_%28computer_science%29"&gt;generators&lt;/a&gt; and the yield function (as found in &lt;a href="http://docs.python.org/ref/yield.html"&gt;Python&lt;/a&gt;). All this functional talk about infinite lists and such I suppose... So I had a go at implementing one in Java, which tied in nicely with my current reflexions about a java-based functional language and the need to provide concurrency out of the box. And another occasion to dabble with wait and notify in Java! After I've written it I found a similar looking &lt;a href="http://d.hatena.ne.jp/lethevert/20070621/p2"&gt;implementation &lt;/a&gt;(but without the standard Iterator/Iterable interface support) and &lt;a href="http://code.google.com/p/infomancers-collections/"&gt;something &lt;/a&gt;on Google code that use bytecode intrumentation (why oh why). But still I like mine, that you can find &lt;a href="http://ted.appspot.com/read/Java/concurrent/Generator.java"&gt;here&lt;/a&gt; (and the unit test is &lt;a href="http://ted.appspot.com/read/Java/concurrent/GeneratorTest.java"&gt;here&lt;/a&gt;).&lt;br /&gt;Basically the work is done in another thread and we call wait() when we do a yield. We conform to the Iterator and the Iterable interfaces, and we provide a stop method to actually stop the thread (say for infinite generators). Otherwise if the generator has not finished the thread goes on waiting forever. I've thought about trying to stop the thread when the generator is not used, but I don't know if it even possible with things like SoftReferences (The thread having a pointer to its runnable...).&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/37404288-3004742437482912923?l=jpmoresmau.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jpmoresmau.blogspot.com/feeds/3004742437482912923/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=37404288&amp;postID=3004742437482912923' title='4 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/37404288/posts/default/3004742437482912923'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/37404288/posts/default/3004742437482912923'/><link rel='alternate' type='text/html' href='http://jpmoresmau.blogspot.com/2007/10/generator-with-yield-in-java.html' title='Generator (with yield) in Java'/><author><name>JP Moresmau</name><uri>http://www.blogger.com/profile/09964251063221757176</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='26' height='32' src='http://4.bp.blogspot.com/_SFBL69b3jRQ/TIUvCsYa5EI/AAAAAAAAACw/4H33zrk1nAI/S220/shades.jpg'/></author><thr:total>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-37404288.post-7879472306936569689</id><published>2007-10-09T17:21:00.000+02:00</published><updated>2007-10-09T17:30:01.284+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Functional Programming'/><category scheme='http://www.blogger.com/atom/ns#' term='Java'/><category scheme='http://www.blogger.com/atom/ns#' term='Haskell'/><title type='text'>My own Java-based functional language</title><content type='html'>I've been toying for a while with the idea of creating my own Java based functional language, if only to be able to see first hand the challenges in creating a functional language. The language I envision has the following characteristics:&lt;br /&gt;- syntax close to Java: contrary to &lt;a href="http://sourceforge.net/projects/jhaskell"&gt;JHaskell&lt;/a&gt; or &lt;a href="http://labs.businessobjects.com/cal/"&gt;CAL&lt;/a&gt;, I want something that looks like Java, not something totally different&lt;br /&gt;- Java type system: use the normal Java OO type system: classes with at most one superclass, interfaces. Maybe I'll run into issues but for the moment...&lt;br /&gt;- pure functional and monadic:  what I love in Haskell is the clear delimitation between what's purely functional and what's subject to side effects (IO, etc...). I'd like to have that in my language. I know about &lt;a href="http://www.scala-lang.org/"&gt;Scala&lt;/a&gt;, but Scala lets you mix functional and imperative code, I want something pure (and I don't like to add new very un-Java like keywords like &lt;span style="font-style: italic;"&gt;def&lt;/span&gt;)!&lt;br /&gt;- Java integration: there is no point of being implemented in Java if we can't reuse the wealth of Java code and libraries out there. Probably I'll need a way to distinguish somehow functional Java code (like the String methods) and not functional code, and wrap access to non functional code in a monad.&lt;br /&gt;&lt;br /&gt;Now that's an ambitious program!! I've started some parsing and conversion to Java source files (hey, if Java can do some of the type checking for me...), but it's going to be a long road...&lt;br /&gt;Of course, if such a language already exists, I'd be delighted to hear about it!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/37404288-7879472306936569689?l=jpmoresmau.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jpmoresmau.blogspot.com/feeds/7879472306936569689/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=37404288&amp;postID=7879472306936569689' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/37404288/posts/default/7879472306936569689'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/37404288/posts/default/7879472306936569689'/><link rel='alternate' type='text/html' href='http://jpmoresmau.blogspot.com/2007/10/my-own-java-based-functional-language.html' title='My own Java-based functional language'/><author><name>JP Moresmau</name><uri>http://www.blogger.com/profile/09964251063221757176</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='26' height='32' src='http://4.bp.blogspot.com/_SFBL69b3jRQ/TIUvCsYa5EI/AAAAAAAAACw/4H33zrk1nAI/S220/shades.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-37404288.post-7666159801840976895</id><published>2007-09-19T13:05:00.000+02:00</published><updated>2007-09-19T13:12:40.682+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Monads'/><category scheme='http://www.blogger.com/atom/ns#' term='Parsec'/><category scheme='http://www.blogger.com/atom/ns#' term='Java'/><category scheme='http://www.blogger.com/atom/ns#' term='parsing'/><category scheme='http://www.blogger.com/atom/ns#' term='Haskell'/><title type='text'>Parser Combinator in Java</title><content type='html'>&lt;span style="font-family: arial;"&gt;Pffuii, I'm quite busy these days, hence the posting frequency has dropped. I'm in the process of playing with a functional Java based language (more on that in later posts, hopefully) and I decided to have a go at a little parser combinator in Java.&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: arial;"&gt;The end result works (I can parse things like Java class declaration) and looks a lot like parsec, but there is a lot of Java cruft that I'd like to remove, things that are hidden with the wonderful magic (I don't understand it well enough to call it otherwise) of Haskell monads.&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: arial;"&gt;For example:&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt;try {&lt;br /&gt;    Character c=new Try(new Letter()).parse(input);&lt;br /&gt;    ...&lt;br /&gt;} catch (JCParseException jpe){&lt;br /&gt;...&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: arial;"&gt;This code tries to match a letter in the input at its current position (the input variable) and does not consume any input if it fails. I don't like having to explicitly tell the combinator to parse the input, and I don't like using exceptions to indicate a parsing failure. Now, anybody has any great ideas?&lt;/span&gt;&lt;br /&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/37404288-7666159801840976895?l=jpmoresmau.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jpmoresmau.blogspot.com/feeds/7666159801840976895/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=37404288&amp;postID=7666159801840976895' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/37404288/posts/default/7666159801840976895'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/37404288/posts/default/7666159801840976895'/><link rel='alternate' type='text/html' href='http://jpmoresmau.blogspot.com/2007/09/parser-combinator-in-java.html' title='Parser Combinator in Java'/><author><name>JP Moresmau</name><uri>http://www.blogger.com/profile/09964251063221757176</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='26' height='32' src='http://4.bp.blogspot.com/_SFBL69b3jRQ/TIUvCsYa5EI/AAAAAAAAACw/4H33zrk1nAI/S220/shades.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-37404288.post-6995694907163637940</id><published>2007-08-10T14:18:00.000+02:00</published><updated>2007-08-10T14:28:42.005+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Parsec'/><category scheme='http://www.blogger.com/atom/ns#' term='HughesPJ'/><category scheme='http://www.blogger.com/atom/ns#' term='Functional Programming'/><category scheme='http://www.blogger.com/atom/ns#' term='parsing'/><category scheme='http://www.blogger.com/atom/ns#' term='Haskell'/><title type='text'>The beauty of Haskell Combinators</title><content type='html'>Pffiuu, it's been a while since I've posted here, but don't think I've been idle. In addition to my day job, I'm still hacking away at Haskell. And still loving it!! I just wanted today to express my pleasure (yes, pleasure) at working with some cool APIs and libraries that are out there.&lt;br /&gt;I'm doing a bit of research into language parsing and I'm using &lt;a href="http://legacy.cs.uu.nl/daan/parsec.html"&gt;Parsec&lt;/a&gt; for parsing and the &lt;a href="http://haskell.org/ghc/docs/latest/html/libraries/base/Text-PrettyPrint-HughesPJ.html"&gt;HughesPJ Pretty Printing&lt;/a&gt; library (included with GHC) to dump the parsed AST and check that I can output what I parse and reparse it into a equivalent structure. I have to say, working with combinators (monadic or otherwise) is actually fun and easy. I've developed code parser before, for example using some Java parser generators, but coding your parser directly in your favorite functional language is really sweet. And of course, I like the way that similar concepts are expressed the same in the two libraries, even down to the function names: &lt;span style="font-style: italic;"&gt;parens()&lt;/span&gt; in Parsec will parse something surrounded but parentheses and &lt;span style="font-style: italic;"&gt;parens()&lt;/span&gt; in HughesPJ will write something in between parenthesis.&lt;br /&gt;I had also a exhilarating ah ah moment when I discovered in the &lt;a href="http://legacy.cs.uu.nl/daan/download/parsec/parsec.html"&gt;Parsec doc&lt;/a&gt; &lt;span style="font-style: italic;"&gt;makeTokenParser&lt;/span&gt; that suddenly made it so easy to accommodate with spaces and pesky littls things of this caliber.&lt;br /&gt;Thanks to all contributors to these libraries for making my functional programming evenings fun!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/37404288-6995694907163637940?l=jpmoresmau.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jpmoresmau.blogspot.com/feeds/6995694907163637940/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=37404288&amp;postID=6995694907163637940' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/37404288/posts/default/6995694907163637940'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/37404288/posts/default/6995694907163637940'/><link rel='alternate' type='text/html' href='http://jpmoresmau.blogspot.com/2007/08/beauty-of-haskell-combinators.html' title='The beauty of Haskell Combinators'/><author><name>JP Moresmau</name><uri>http://www.blogger.com/profile/09964251063221757176</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='26' height='32' src='http://4.bp.blogspot.com/_SFBL69b3jRQ/TIUvCsYa5EI/AAAAAAAAACw/4H33zrk1nAI/S220/shades.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-37404288.post-8778795192318864897</id><published>2007-06-01T13:12:00.000+02:00</published><updated>2007-06-01T13:15:30.808+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Functional Programming'/><category scheme='http://www.blogger.com/atom/ns#' term='Artificial Intelligence'/><category scheme='http://www.blogger.com/atom/ns#' term='Haskell'/><title type='text'>A very dumb neural network in Haskell</title><content type='html'>Continuing my implementations of Michael Negnevitsky book on Artifical Intelligence in Haskell, I have tried to code a three layer neural network to implement exclusive or (Intelligence indeed...).&lt;br /&gt;&lt;br /&gt;A neuron is made of its input weight and its threshold, and its output is calculated thus (apologies to all of you who gave me some tips about parameter order and newtype declaration, I haven't changed the code yet to follow your good advice!):&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;type Neuron= ([Value],Value)&lt;br /&gt;type Value = Float&lt;br /&gt;&lt;br /&gt;neuronOutput :: [Value] -&gt; Neuron -&gt; Value&lt;br /&gt;neuronOutput inputs (weights,threshold) =&lt;br /&gt;    let&lt;br /&gt;        tot=(foldl (+) 0 (zipWith (*) inputs weights)) - threshold&lt;br /&gt;    in&lt;br /&gt;        1 / (1 + ((2.7182) ** (-tot)))&lt;br /&gt;&lt;/pre&gt;     &lt;br /&gt;   &lt;br /&gt;A three layer network whose input layer does nothing but fire its input to the midle layer can be modelled by to lists of neurons, and I use a TestCase type to keep track of inputs and expected outputs&lt;br /&gt;&lt;pre&gt;       &lt;br /&gt;type Network = ([Neuron],[Neuron])&lt;br /&gt;type TestCase = ([Value],[Value])&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Running the whole network with some input values is easy:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;exec ::  Network -&gt; [Value] -&gt; ([Value],[Value])&lt;br /&gt;exec (hidden,output) inputs =&lt;br /&gt;    let&lt;br /&gt;        hiddenOutputs = map (neuronOutput inputs) hidden&lt;br /&gt;        outputOutputs = map (neuronOutput hiddenOutputs) output&lt;br /&gt;    in&lt;br /&gt;        (hiddenOutputs,outputOutputs)&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;The meat is all in one function, that calculates the output of the network for a given test and adapts the weights accordingly, first for the output layer then for the hidden layer:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;defaultLearningRate::Value&lt;br /&gt;defaultLearningRate=0.1&lt;br /&gt;&lt;br /&gt;step ::  (Network,Value) -&gt; TestCase -&gt; (Network,Value)&lt;br /&gt;step ((hidden,output),err) (inputs,expected)=&lt;br /&gt;    let&lt;br /&gt;        (hiddenOutputs,outputOutputs)=exec (hidden,output) inputs&lt;br /&gt;        errorOutputs= zipWith (-) expected outputOutputs&lt;br /&gt;        gradientOutputs=zipWith (\o d-&gt;o*(1-o)*d) outputOutputs errorOutputs&lt;br /&gt;        newOutputs=zipWith (\(ws,t) g -&gt; ( zipWith (\h w-&gt;w+ (defaultLearningRate*h*g)) hiddenOutputs ws ,t+(defaultLearningRate*g*(-1)))) output gradientOutputs&lt;br /&gt;        weightsByHidden= transpose (map fst output)&lt;br /&gt;        gradientHidden =zipWith (\o ws-&gt; o * (1-o) * (foldl (+) 0 (zipWith (*) ws gradientOutputs))) hiddenOutputs weightsByHidden&lt;br /&gt;        newHidden=zipWith (\(ws,t) g -&gt; ( zipWith (\h w-&gt;w+ (defaultLearningRate*h*g)) inputs ws ,t+(defaultLearningRate*g*(-1)))) hidden gradientHidden&lt;br /&gt;        newErr=err + (foldl (+) 0 (map (^2) errorOutputs))&lt;br /&gt;    in ((newHidden,newOutputs),newErr)&lt;br /&gt; &lt;/pre&gt;&lt;br /&gt;The result is a new adapted network and the sum of squared errors.&lt;br /&gt;   &lt;br /&gt;An epoch is a set of tests:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;epoch :: Network -&gt; [TestCase] -&gt; (Network,Value)&lt;br /&gt;epoch network= foldl step (network,0)&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;We can then repeat epoch till the sum of squared errors for an epoch is less than the threshold for convergence:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;errorConvergence::Value&lt;br /&gt;errorConvergence=0.001&lt;br /&gt;&lt;br /&gt;run ::     Network -&gt; [TestCase] -&gt; Int -&gt; (Network,Int,Value)&lt;br /&gt;run network allInputs epochNb=&lt;br /&gt;    let (newNetwork,delta) = epoch network allInputs&lt;br /&gt;    in (?) (delta &lt;= errorConvergence || epochNb&gt;225)&lt;br /&gt;            (newNetwork, epochNb,delta)&lt;br /&gt;            (run newNetwork allInputs (epochNb+1))&lt;br /&gt;   &lt;br /&gt;(?) :: Bool -&gt; a -&gt; a -&gt; a&lt;br /&gt;(?) True a _  = a&lt;br /&gt;(?) False _ a = a&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;(Is there a standard function for (?)? I got tired of if then else...)&lt;br /&gt;&lt;br /&gt;Then I test my code with the same start network as in the book:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;test = do&lt;br /&gt;    let n = ([([0.5,0.4],0.8),([0.9,1.0],-0.1)],[([-1.2,1.1],0.3)])&lt;br /&gt;    let (n',e,err) = run n [([1,1],[0]),([0,1],[1]),([1,0],[1]),([0,0],[0])] 1&lt;br /&gt;    print (n',e,err)&lt;br /&gt;    return ()&lt;br /&gt;&lt;/pre&gt;  &lt;br /&gt;And I get a mixed feeling about the result: the network does converge, and then it does work, but after something like 54000 epochs, while in the book it supposedly take 224! The book gives the result for the first test and I'm getting exactly the same thing, but it looks like my network learns a lot slower than it should. I would suppose I have a subtle error somewhere, but for the life of me I can't find it... If it jumps at anybody, please let me know. My hope now is that when refactoring the code and following the books advice on improving the performance I will find the bug!!&lt;br /&gt;&lt;br /&gt;I have tried with random networks:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;network :: Int -&gt; Int -&gt; Int-&gt; IO Network&lt;br /&gt;network inputNb hiddenNb outputNb= do&lt;br /&gt;    a&lt;-randomNeurons inputNb hiddenNb&lt;br /&gt;    b&lt;-randomNeurons hiddenNb outputNb&lt;br /&gt;    return (a,b)&lt;br /&gt;   &lt;br /&gt;randomNeurons:: Int -&gt; Int -&gt; IO [Neuron]&lt;br /&gt;randomNeurons nbInput nbNeurons= replicateM nbNeurons (randomNeuron nbInput)&lt;br /&gt;   &lt;br /&gt;randomNeuron:: Int -&gt; IO Neuron&lt;br /&gt;randomNeuron nb= do&lt;br /&gt;    w&lt;-replicateM nb (randomWeight nb)&lt;br /&gt;    t&lt;-randomWeight nb&lt;br /&gt;    return (w,t)&lt;br /&gt;   &lt;br /&gt;randomWeight:: Int -&gt; IO Value&lt;br /&gt;randomWeight nbInput= do&lt;br /&gt;    let interval= randomR ((-2.4)/(fromIntegral nbInput),2.4/(fromIntegral nbInput))&lt;br /&gt;    getStdRandom interval&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;But I don't get better results...&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/37404288-8778795192318864897?l=jpmoresmau.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jpmoresmau.blogspot.com/feeds/8778795192318864897/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=37404288&amp;postID=8778795192318864897' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/37404288/posts/default/8778795192318864897'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/37404288/posts/default/8778795192318864897'/><link rel='alternate' type='text/html' href='http://jpmoresmau.blogspot.com/2007/06/very-dumb-neural-network-in-haskell.html' title='A very dumb neural network in Haskell'/><author><name>JP Moresmau</name><uri>http://www.blogger.com/profile/09964251063221757176</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='26' height='32' src='http://4.bp.blogspot.com/_SFBL69b3jRQ/TIUvCsYa5EI/AAAAAAAAACw/4H33zrk1nAI/S220/shades.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-37404288.post-4207788230397604070</id><published>2007-05-25T14:12:00.000+02:00</published><updated>2007-05-25T14:15:08.952+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Functional Programming'/><category scheme='http://www.blogger.com/atom/ns#' term='Artificial Intelligence'/><category scheme='http://www.blogger.com/atom/ns#' term='Haskell'/><title type='text'>A perceptron in Haskell</title><content type='html'>After reading Michael Negnevitsky book on Artifical Intelligence, I started playing with some of the algorithms he gives in Haskell. So my first endeavour is writing a simple perceptron (a one neuron neural network) to perform AND or OR logical operations. Next I'll start a full multi layer network to do much more complex operations like exclusive OR (-:.&lt;br /&gt;Once again I was struck with the simplicity of the Haskell code necessary to implement such functionality (and I'm no Haskell expert yet). You think about how you going to implement it, the type checker tells you when you're doing something stupid, and by the time everything is written and compiles it kinda works.&lt;br /&gt;The core method is calculating the output of the neuron, given the inputs, the weight of each input and the threshold value for that neuron:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;neuronOutput :: [Float] -&gt; [Float] -&gt; Float -&gt; Float&lt;br /&gt;neuronOutput inputs weights threshold =&lt;br /&gt;    let&lt;br /&gt;        tot=(foldl (+) 0 (zipWith (*) inputs weights)) - threshold&lt;br /&gt;    in&lt;br /&gt;        if tot &gt;= 0&lt;br /&gt;            then 1&lt;br /&gt;            else 0&lt;br /&gt;&lt;/pre&gt;      &lt;br /&gt;Using zipWith we multiply each input with its weigth, calculate the sum with fold and remove the threshold. A negative result yields 0, else it yields 1.&lt;br /&gt;&lt;br /&gt;Adjusting the weights to adapt to the error of a test case is no more difficult:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;defaultLearningRate::Float&lt;br /&gt;defaultLearningRate=0.1&lt;br /&gt;&lt;br /&gt;adjustWeights :: [Float] -&gt; [Float] -&gt; Float -&gt; Float -&gt; [Float]&lt;br /&gt;adjustWeights inputs origWeights expected actual =&lt;br /&gt;    let&lt;br /&gt;        e=expected - actual&lt;br /&gt;        delta (i,w) = w + (defaultLearningRate * i * e)&lt;br /&gt;    in&lt;br /&gt;        map delta (zip inputs origWeights)&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;We modify the weight by applying to each weight a delta that is dependant on the input weight, the error ratio and the learning rat&lt;br /&gt;&lt;br /&gt;A single step is made of calculating the output of the neuron and adapting the weights, given the expected value:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;defaultThreshold::Float&lt;br /&gt;defaultThreshold=0.2&lt;br /&gt;&lt;br /&gt;step :: [Float] -&gt; [Float] -&gt; Float -&gt; [Float]&lt;br /&gt;step inputs weights expected=&lt;br /&gt;    let&lt;br /&gt;        o = neuronOutput inputs weights defaultThreshold&lt;br /&gt;    in&lt;br /&gt;        adjustWeights inputs weights expected o   &lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Then an epoch applies the step function to each different input sets. The hardest part is calculating the average of all deltas to find if the weights have changed at all during the evaluation of all the test cases&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;epoch :: [([Float],Float)] -&gt; [Float] -&gt; ([Float],Float)&lt;br /&gt;epoch allInputs weights=&lt;br /&gt;    let&lt;br /&gt;        f w (inputs,expected) = step inputs w expected&lt;br /&gt;        newWeights=foldl f weights allInputs&lt;br /&gt;        delta= (foldl (+) 0 (map abs (zipWith (-) newWeights weights))) / (fromIntegral $ length weights)&lt;br /&gt;    in (newWeights,delta)&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;A training run is only launching the epoch function repeatedly till the delta is zero:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;run ::     [([Float],Float)] -&gt; [Float] -&gt; Int -&gt; ([Float],Int)&lt;br /&gt;run allInputs weights epochNb=&lt;br /&gt;    let (newWeights,delta) = epoch allInputs weights&lt;br /&gt;    in if delta == 0&lt;br /&gt;        then&lt;br /&gt;            (newWeights, epochNb)&lt;br /&gt;        else&lt;br /&gt;            run allInputs newWeights (epochNb+1)&lt;br /&gt;&lt;/pre&gt;      &lt;br /&gt;We generate the initial weights in the IO monad, passing the number of weights needed:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;initialWeights :: Int -&gt; IO [Float]&lt;br /&gt;initialWeights nb = do&lt;br /&gt;    let interval= randomR (-0.5,0.5)&lt;br /&gt;    (replicateM nb (getStdRandom interval))&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Putting it all together:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;test :: IO()&lt;br /&gt;test = do&lt;br /&gt;    w&lt;-initialWeights 2&lt;br /&gt;    let (ws,i)=run [([0,0],0),([0,1],0),([1,0],0),([1,1],1)] w 1&lt;br /&gt;    print (ws,i)&lt;br /&gt;    return ()&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;test find out the proper weights to implement AND and print them out, with the number of epochs needed to reach the result. You can then call neuronOutput with the resulting weights and your input: you have a AND logical gate!&lt;br /&gt;&lt;br /&gt;As usual, any pointer to how to improve the code is welcome!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/37404288-4207788230397604070?l=jpmoresmau.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jpmoresmau.blogspot.com/feeds/4207788230397604070/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=37404288&amp;postID=4207788230397604070' title='5 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/37404288/posts/default/4207788230397604070'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/37404288/posts/default/4207788230397604070'/><link rel='alternate' type='text/html' href='http://jpmoresmau.blogspot.com/2007/05/perceptron-in-haskell.html' title='A perceptron in Haskell'/><author><name>JP Moresmau</name><uri>http://www.blogger.com/profile/09964251063221757176</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='26' height='32' src='http://4.bp.blogspot.com/_SFBL69b3jRQ/TIUvCsYa5EI/AAAAAAAAACw/4H33zrk1nAI/S220/shades.jpg'/></author><thr:total>5</thr:total></entry><entry><id>tag:blogger.com,1999:blog-37404288.post-5425524526608079547</id><published>2007-05-16T13:38:00.000+02:00</published><updated>2007-05-16T13:42:41.523+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='JavaScript'/><category scheme='http://www.blogger.com/atom/ns#' term='Functional Programming'/><category scheme='http://www.blogger.com/atom/ns#' term='Rhino'/><category scheme='http://www.blogger.com/atom/ns#' term='Hibernate'/><category scheme='http://www.blogger.com/atom/ns#' term='functions'/><title type='text'>Javascript and Hibernate, hand in hand</title><content type='html'>&lt;span style="font-size:85%;"&gt;Some time ago I had written a little prototype that was quite interesting, but I never pursued it. Maybe I should try to get some people interested and develop it further...&lt;br /&gt;The idea was to use Rhino to have a Javascript-based framework on the server, thus using the same language on the server and on the client, like ASP did in the good old days. I was also thinking of having the source code for custom applications stored in the database, instead of having it in source files, but that's another story. That explains why the examples below are about "applications" and "components"&lt;br /&gt;The first component is Hibernate connectivity. My framework lets you:&lt;br /&gt;1. Dynamically configure Hibernate mapping for Javascript defined classes. For example, if you wanted to define a Web Application with several attributes and a reference to the components that it defines:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;function Application(){&lt;br /&gt; this.displayName='';&lt;br /&gt; this.urlName='';&lt;br /&gt; this.defaultUrl='';&lt;br /&gt; this.id=-1;&lt;br /&gt; this.components=[];&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Application.storage(&lt;br /&gt; {&lt;br /&gt; id:&lt;br /&gt;  {name:'id',column:'ID',type:'long'},&lt;br /&gt; properties: &lt;br /&gt;  [&lt;br /&gt;   {name:'displayName','not-null':true},&lt;br /&gt;   {name:'urlName','not-null':true,unique:true,'unique-key':'APPLICATION_URL'},&lt;br /&gt;   {name:'defaultUrl'}&lt;br /&gt;  ], &lt;br /&gt; references:&lt;br /&gt;  [&lt;br /&gt;   {'list':&lt;br /&gt;    {name:'components',table:'APPLICATION_COMPONENT',&lt;br /&gt;     details:[&lt;br /&gt;      {'key':{column:'APPLICATIONID'}},&lt;br /&gt;      {'list-index':{column:'idx',base:'0'}},&lt;br /&gt;      {'many-to-many':{'column':'COMPONENTID','class':'Component'}}&lt;br /&gt;     ]&lt;br /&gt;    }&lt;br /&gt;   }&lt;br /&gt;  ]&lt;br /&gt; }&lt;br /&gt; );&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Note that storage() is a function of the Function object which takes a Javascript structure that mimicks the Hibernate XML.&lt;br /&gt;&lt;br /&gt;2. Access Hibernate functionality through a "hibernate" host object. For example, a JSUnit method testing the addition of a new "Application" object:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;var appId;&lt;br /&gt;var appUrlName;&lt;br /&gt;&lt;br /&gt;function testAdd(){&lt;br /&gt; assertNotUndefined(hibernate);&lt;br /&gt; var app=new Application();&lt;br /&gt; assertNotUndefined(app);&lt;br /&gt; app.displayName="TestAppJS"+new Date();&lt;br /&gt; app.urlName=app.displayName;&lt;br /&gt; appUrlName=app.urlName;&lt;br /&gt; hibernate.save(app);&lt;br /&gt; hibernate.commit();&lt;br /&gt; assertNotNaN(app.id);&lt;br /&gt; assertTrue(app.id&gt;0);&lt;br /&gt; appId=app.id;&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;The hibernate object lets you list objects, get a particular object, modify or create instances, etc. I have implemented a Hibernate EntityTuplizer and an subclass of Rhino's NativeArray that encapsulate a PersistentList, so that multiples references can be seen as Javascript arrays.&lt;br /&gt;&lt;br /&gt;3. Query the database either through the HQL language:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;var apps=hibernate.query("from Application where urlName=?",["TestAppJS"]);&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;or through a pure Javascript function based mechanism:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;var apps=hibernate.query("Application",function(app){&lt;br /&gt; return app.urlName=="TestAppJS";}&lt;br /&gt;);&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;That I think is very cool. In Rhino I can access the source code of the function that is passed as the second argument to query, and transform it into HQL. I haven't implemented as much as I could, of course, but it works with simple queries. At least there is no other syntax to learn to do a query, it's basically the equivalent of a filter function in functional language.&lt;br /&gt;&lt;br /&gt;Then I had started to develop a web framework (probably the millioneth Java web framework by now) with Javascript objects to generate HTML and a mapping between urls and javascript functions, and where one URL could chain several functions, but I haven't gone very far.&lt;br /&gt;&lt;br /&gt;Now if somebody feels there's some value in any of that I can sure post the code and we can move it forward. Anything that can show that Javascript is a cool language to run in a JVM in a worthwhile enterprise (-:&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/37404288-5425524526608079547?l=jpmoresmau.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jpmoresmau.blogspot.com/feeds/5425524526608079547/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=37404288&amp;postID=5425524526608079547' title='5 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/37404288/posts/default/5425524526608079547'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/37404288/posts/default/5425524526608079547'/><link rel='alternate' type='text/html' href='http://jpmoresmau.blogspot.com/2007/05/javascript-and-hibernate-hand-in-hand.html' title='Javascript and Hibernate, hand in hand'/><author><name>JP Moresmau</name><uri>http://www.blogger.com/profile/09964251063221757176</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='26' height='32' src='http://4.bp.blogspot.com/_SFBL69b3jRQ/TIUvCsYa5EI/AAAAAAAAACw/4H33zrk1nAI/S220/shades.jpg'/></author><thr:total>5</thr:total></entry><entry><id>tag:blogger.com,1999:blog-37404288.post-2012523813940867553</id><published>2007-05-11T13:32:00.000+02:00</published><updated>2007-05-11T13:51:44.486+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='JavaScript'/><category scheme='http://www.blogger.com/atom/ns#' term='JSON'/><category scheme='http://www.blogger.com/atom/ns#' term='Java'/><category scheme='http://www.blogger.com/atom/ns#' term='JavaFX'/><category scheme='http://www.blogger.com/atom/ns#' term='RIA'/><category scheme='http://www.blogger.com/atom/ns#' term='Flex'/><category scheme='http://www.blogger.com/atom/ns#' term='GUI'/><title type='text'>Poor man's JavaFX Script is, er... Javascript</title><content type='html'>&lt;span style=";font-family:verdana;font-size:85%;"  &gt;Sun has release its own RIA framework called &lt;a href="https://openjfx.dev.java.net/"&gt;Java FX&lt;/a&gt;. It provide JavaFX Script, which is a language based on Java whose goal is to develop quickly graphical applications with the power of Java. Is it touted as competition to Flex that I have mentioned before. It is safe to say that it hasn't been received with a &lt;a href="http://www.theserverside.com/news/thread.tss?thread_id=45331"&gt;great deal of enthusiasm&lt;/a&gt;. The fact is, I don't want to learn another language again to do my Web 2.0 application. And I do believe that &lt;a href="http://www.ics.uci.edu/%7Efielding/pubs/dissertation/evaluation.htm"&gt;Fielding&lt;/a&gt; has a point when he reflects that applets break visibility and raise the barrier of entry for web developers. Also, I'm usually all in favor of static typing and compilation, but for GUIs I'm not too sure. When you want to tweak your borders or your layouts you probably happy enough with a quick cycle of change code/refresh page. So why don't we use Javascript and Java Applets together instead of inventing yet another technology?&lt;br /&gt;Ok, it's time you get over your irrational distrust of Javascript. A multi paradigm (object, functional) language available for free in every browser!! And no, I don't suggest we go on using the HTML DOM or things like that. That's why we need applets.&lt;br /&gt;Applets? I must be mad! Applets have not worked on the web. But what I suggest is not to develop one applet for each RIA application, but only develop one Applet that everybody could use, much like a plugin, that would bridge the gap between the JavaScript world and the Java/Swing world. If it has been done, please let me know. As for me, I've put together a prototype in an hour that works fine:&lt;br /&gt;&lt;/span&gt;&lt;ol  style="font-family:verdana;font-size:85%;"&gt;&lt;li&gt;&lt;span style="font-size:85%;"&gt;The JavaScript code constructs an object tree that represents the GUI.&lt;br /&gt;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-size:85%;"&gt;The object tree is serialized to JSON and passed on to the applet&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-size:85%;"&gt;The applet deserializes the JSON and constructs a Swing GUI by translating the object tree&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-size:85%;"&gt;The object tree can contain handlers that are the names of Javascript functions&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-size:85%;"&gt;The applet calls the javascript functions on Swing events&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-size:85%;"&gt;The JavaScript event handlers update the GUI tree and notify the applet with the changes.&lt;/span&gt;&lt;/li&gt;&lt;/ol&gt;&lt;span style="font-size:85%;font-family:verdana;"&gt;A very simple example:&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;&amp;lt;html&amp;gt;&lt;br /&gt;&amp;lt;head&amp;gt;&amp;lt;title&amp;gt;JSApplet&amp;lt;/title&amp;gt;&lt;br /&gt;&lt;br /&gt;&amp;lt;script language="Javascript"&amp;gt;&lt;br /&gt;&lt;br /&gt;var helloButton={type:"button","id":"helloButton","text":"hello","action":onClickHello}&lt;br /&gt;var frame={"contents":&lt;br /&gt; [&lt;br /&gt;  helloButton&lt;br /&gt; ]&lt;br /&gt; };&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;function onClickHello(){&lt;br /&gt; helloButton.text=helloButton.text.toUpperCase();&lt;br /&gt; updateJS([helloButton])&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;function startJS(){&lt;br /&gt; var msg=document.getElementById("JSApplet").setContent(toJSON(frame));&lt;br /&gt; if (msg){&lt;br /&gt;  alert(msg);&lt;br /&gt; }&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;function updateJS(objs){&lt;br /&gt; var msg=document.getElementById("JSApplet").updateContent(toJSON(objs));&lt;br /&gt; if (msg){&lt;br /&gt;  alert(msg);&lt;br /&gt; }&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;toJSON=function(arg) {&lt;br /&gt;    &lt;br /&gt;    switch (typeof arg) {&lt;br /&gt;    case 'object':&lt;br /&gt;        if (arg) {&lt;br /&gt;            if (arg.constructor == Array) {&lt;br /&gt;                var o = '';&lt;br /&gt;                for (var i = 0; i &amp;lt; arg.length; ++i) {&lt;br /&gt;                    var v = toJSON(arg[i]);&lt;br /&gt;                    if (o) {&lt;br /&gt;                        o += ',';&lt;br /&gt;                    }&lt;br /&gt;                    if (v != null) {&lt;br /&gt;                        o += v;&lt;br /&gt;                    } else {&lt;br /&gt;                        o += 'null,';&lt;br /&gt;                    }&lt;br /&gt;                }&lt;br /&gt;                return '[' + o + ']';&lt;br /&gt;            } else if (typeof arg.toString != 'undefined') {&lt;br /&gt;                var o = '';&lt;br /&gt;                for (var i in arg) {&lt;br /&gt;                    var v = toJSON(arg[i]);&lt;br /&gt;                    if (v != null) {&lt;br /&gt;                        if (o) {&lt;br /&gt;                            o += ',';&lt;br /&gt;                        }&lt;br /&gt;                        o += toJSON(i) + ':' + v;&lt;br /&gt;                    }&lt;br /&gt;                }&lt;br /&gt;                return '{' + o + '}';&lt;br /&gt;            } else {&lt;br /&gt;                return;&lt;br /&gt;            }&lt;br /&gt;        }&lt;br /&gt;        return 'null';&lt;br /&gt;    case 'unknown':&lt;br /&gt;    case 'undefined':&lt;br /&gt;    case 'function':&lt;br /&gt;     return arg.name;&lt;br /&gt;    case 'string':&lt;br /&gt;        return '"' + arg.replace(/(["\\])/g, '\\$1') + '"';&lt;br /&gt;    default:&lt;br /&gt;        return String(arg);&lt;br /&gt;    }&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&amp;lt;/script&amp;gt;&lt;br /&gt;&amp;lt;/head&amp;gt;&lt;br /&gt;&amp;lt;body onload="startJS();"&amp;gt;&lt;br /&gt;&amp;lt;applet id="JSApplet" alt="JSApplet" code="fr/moresmau/jp/jsapplet/JSApplet.class" codebase="bin" mayscript="mayscript" height="100" width="100"&amp;gt;&amp;lt;/applet&amp;gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&amp;lt;/body&amp;gt;&lt;br /&gt;&amp;lt;/html&amp;gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;span style=";font-family:verdana;font-size:85%;"  &gt;&lt;br /&gt;This web page creates a simple "Hello" button that when clicked changed its text to upperCase(). It demonstrate the two ways communication between the Javascript code and the applet (note how the function is serialized in JSON just with its name, that's the only thing we need). So the Javascript can deal with a model that is a slightly abstracted Swing model (no more hair pulling between different browsers). I stress again, the applet is a generic applet that deals with the link between the JSON objects and the Swing layer. Of course the applet could offer other services: simple API to call back the server (AJAX from the applet), etc...&lt;br /&gt;Then the applet could be packaged with a cut down version of the JRE (only the classes really needed) as a plugin to do rich Swing application from JavaScript...&lt;br /&gt;And voilà! A scriptable RIA platform!&lt;br /&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/37404288-2012523813940867553?l=jpmoresmau.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jpmoresmau.blogspot.com/feeds/2012523813940867553/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=37404288&amp;postID=2012523813940867553' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/37404288/posts/default/2012523813940867553'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/37404288/posts/default/2012523813940867553'/><link rel='alternate' type='text/html' href='http://jpmoresmau.blogspot.com/2007/05/poor-mans-javafx-script-is-er.html' title='Poor man&apos;s JavaFX Script is, er... Javascript'/><author><name>JP Moresmau</name><uri>http://www.blogger.com/profile/09964251063221757176</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='26' height='32' src='http://4.bp.blogspot.com/_SFBL69b3jRQ/TIUvCsYa5EI/AAAAAAAAACw/4H33zrk1nAI/S220/shades.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-37404288.post-2500292613406264869</id><published>2007-04-20T13:28:00.000+02:00</published><updated>2007-04-20T13:38:18.294+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Java'/><category scheme='http://www.blogger.com/atom/ns#' term='Flex'/><category scheme='http://www.blogger.com/atom/ns#' term='GUI'/><category scheme='http://www.blogger.com/atom/ns#' term='Haskell'/><title type='text'>Haskell code, Java UI</title><content type='html'>It's been while since I've posted anything, mainly because work crises and holidays have kept me busy or away from my keyboard. I'm still playing with Haskell and user interfaces, I've now developed the same Maze game in HGL, Flex with a Haskell web back end, and &lt;a href="http://wxhaskell.sourceforge.net/"&gt;WXHaskell&lt;/a&gt;. I've looked at trying to implement some declarative syntax that would simplify WXHaskell code but haven't gone very far, I think I'm trying to run in Haskell before I can walk straight!&lt;br /&gt;Anyway, I was looking at Business Objects' Quark framework based on the CAL language. You can find more details &lt;a href="http://labs.businessobjects.com/cal/"&gt;here&lt;/a&gt;, but basically CAL is a Haskell-inspired impure functional language implemented in Java, that can  use Java classes and methods. The impurity comes from not using monads to access Java, if I understand well, which means that you can declare pure functional methods that in fact access Java objects, that can do all kind of stateful voodoo under the covers.  While I'm not sure this is really A Good Thing, having Haskell and Java intertwined brings some interesting ideas in the realm of Haskell UIs. Swing and Java are now mature, reasonably fast and cross platform. If I can get my pure Haskell code to talk to a Java GUI, I could get quite happy indeed...&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/37404288-2500292613406264869?l=jpmoresmau.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jpmoresmau.blogspot.com/feeds/2500292613406264869/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=37404288&amp;postID=2500292613406264869' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/37404288/posts/default/2500292613406264869'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/37404288/posts/default/2500292613406264869'/><link rel='alternate' type='text/html' href='http://jpmoresmau.blogspot.com/2007/04/haskell-code-java-ui.html' title='Haskell code, Java UI'/><author><name>JP Moresmau</name><uri>http://www.blogger.com/profile/09964251063221757176</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='26' height='32' src='http://4.bp.blogspot.com/_SFBL69b3jRQ/TIUvCsYa5EI/AAAAAAAAACw/4H33zrk1nAI/S220/shades.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-37404288.post-8485665538799721887</id><published>2007-03-30T15:18:00.001+02:00</published><updated>2008-07-09T11:07:46.285+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='games'/><category scheme='http://www.blogger.com/atom/ns#' term='JSON'/><category scheme='http://www.blogger.com/atom/ns#' term='mazes'/><category scheme='http://www.blogger.com/atom/ns#' term='Flex'/><category scheme='http://www.blogger.com/atom/ns#' term='GUI'/><category scheme='http://www.blogger.com/atom/ns#' term='Haskell'/><title type='text'>A Haskell GUI in Flex</title><content type='html'>&lt;span style="font-size:85%;"&gt;&lt;a href="http://jpmoresmau.blogspot.com/2007/02/haskell-user-interface.html"&gt;In an earlier post&lt;/a&gt; I mentioned a little Haskell game I developed where you had to navigate in a maze. I used HGL as the GUI framework, and noted it wasn't very clear what was the functional GUI framework of choice for Haskell. So I decided to give Flex a go and to hook it up with my Haskell back-end. I'm quite please with the result, I have to say.&lt;br /&gt;The setup is as follows:&lt;br /&gt;1) I've implemented a very simple single-threaded HTTP server in Haskell, using as an inspiration code that I found here and there (using &lt;a href="http://www.cs.uu.nl/%7Edaan/parsec.html"&gt;Parsec &lt;/a&gt;for parsing HTTP messages, etc.). The server can server static HTML and SWF files as well as having a dynamic component: you can register Haskell methods that take a &lt;a href="http://www.json.org/"&gt;JSON&lt;/a&gt; object as a parameter, some internal state and return a new JSON object and the new state (yes I know, there is a monad for that...). I used the code &lt;a href="http://www.tom.sfc.keio.ac.jp/%7Esakai/d/data/200604/JSON.hs"&gt;here&lt;/a&gt; for JSON in Haskell. I thus expose a method that generates a Maze and a method to move to a cell, validating that there is no wall in between the current cell and the target cell and checking to see if we reached the exit.&lt;br /&gt;2) I use Flex and ActionScript to create the GUI. The compiled SWF file will be served by the Haskell server and will call it back through asynchronous calls. I was a bit taken aback when I realized that Flex doesn't come with JSON support out of the box, but luckily there's a &lt;a href="http://code.google.com/p/as3corelib/"&gt;library for it&lt;/a&gt;. So you connect via your browser to a page on the server that embeds the SWF, Flex ask for the maze data to the server and displays it, and let you navigate using the keyboards or the mouse.&lt;br /&gt;And that's it! So I have a nice, platform independent GUI and functional business code. I was thinking, who needs a special GUI framework for the desktop when an application could be made easily with a very lightweight local HTTP server and a web based interface? I even thought that Flex was a bit too much: why do I need a GUI technology that requires compilation when I can do nice stuff with pure HTML/Javascript frameworks like &lt;a href="http://dojotoolkit.org/"&gt;Dojo&lt;/a&gt;? So I can use a UI technology that is purely for UIs, and a functional language with the goodies Haskell provide for all the back-end, computation-heavy work.&lt;br /&gt;The code for Haskell is &lt;a href="http://ted.appspot.com/search"&gt;here&lt;/a&gt; (start from Framework.hs), the Flex code is &lt;a href="http://ted.appspot.com/read/Flex/Maze/shape.mxml"&gt;here&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/37404288-8485665538799721887?l=jpmoresmau.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jpmoresmau.blogspot.com/feeds/8485665538799721887/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=37404288&amp;postID=8485665538799721887' title='10 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/37404288/posts/default/8485665538799721887'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/37404288/posts/default/8485665538799721887'/><link rel='alternate' type='text/html' href='http://jpmoresmau.blogspot.com/2007/03/haskell-gui-in-flex.html' title='A Haskell GUI in Flex'/><author><name>JP Moresmau</name><uri>http://www.blogger.com/profile/09964251063221757176</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='26' height='32' src='http://4.bp.blogspot.com/_SFBL69b3jRQ/TIUvCsYa5EI/AAAAAAAAACw/4H33zrk1nAI/S220/shades.jpg'/></author><thr:total>10</thr:total></entry><entry><id>tag:blogger.com,1999:blog-37404288.post-5495543903173200714</id><published>2007-03-23T13:39:00.000+01:00</published><updated>2007-03-23T13:42:06.592+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='closures'/><category scheme='http://www.blogger.com/atom/ns#' term='Java'/><category scheme='http://www.blogger.com/atom/ns#' term='scripting'/><category scheme='http://www.blogger.com/atom/ns#' term='functions'/><title type='text'>Dynamic class behaviour in Java</title><content type='html'>&lt;span style="font-size:85%;"&gt;In a &lt;a href="http://jpmoresmau.blogspot.com/2006/11/higher-order-functions-in-java-with.html"&gt;previous post&lt;/a&gt;, I was using annotations to generate method pointers in Java. The functions objects were generated in a separate class file. However, if you suppose that a modern IDE would be able to generate all that code for you when you create a method, you could have the function object in the same class file as the method code itself. Since Java allows you to have a field and a method with the same name, everything works fine.&lt;br /&gt;In that previous post the function object referenced the actual method in the original class file. What if we did the opposite, that is to say, the actual code is in the function object, and the method merely delegates? Here is a trivial example:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;public class StringHelperDynamic {&lt;br /&gt;&lt;br /&gt;    public String toUpper(String a){&lt;br /&gt;        return toUpper.run(a);&lt;br /&gt;    }&lt;br /&gt;   &lt;br /&gt;    public Function1&lt;java.lang.string,&gt; toUpper = new         Function1&lt;java.lang.string,&gt; (this){&lt;br /&gt;            public java.lang.String run(java.lang.String a) {&lt;br /&gt;                return a.toUpperCase();&lt;br /&gt;            }&lt;br /&gt;        };&lt;br /&gt;   &lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Here, we have a toUpper method that takes a String and return a String, and a toUpper function object that we can pass around, perform currying on, etc... the interesting twist of this architecture is that the toUpper field can be final or not. If not, we can then change it at runtime, and hence change the behaviour of the class at runtime, while still calling the same methods. Who needs a dynamic scripting language (-: ? To the silly example:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;StringHelperDynamic me=new StringHelperDynamic();&lt;br /&gt;me.toUpper=new Function1&lt;string,string&gt;(me){&lt;br /&gt;    public java.lang.String run(java.lang.String a) {&lt;br /&gt;        return a.toLowerCase();&lt;br /&gt;    }&lt;br /&gt;};&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;assertEquals("hello",me.toUpper("HELLO"));&lt;br /&gt;&lt;br /&gt;OK, breaking the contract of the method is NOT what this is about, but you get the gist of it. The code for the Function1 class can be found &lt;a href="http://www.moresmau.fr/jp/java/src/fr/moresmau/jp/func"&gt;here&lt;/a&gt;.&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/37404288-5495543903173200714?l=jpmoresmau.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jpmoresmau.blogspot.com/feeds/5495543903173200714/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=37404288&amp;postID=5495543903173200714' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/37404288/posts/default/5495543903173200714'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/37404288/posts/default/5495543903173200714'/><link rel='alternate' type='text/html' href='http://jpmoresmau.blogspot.com/2007/03/dynamic-class-behaviour-in-java.html' title='Dynamic class behaviour in Java'/><author><name>JP Moresmau</name><uri>http://www.blogger.com/profile/09964251063221757176</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='26' height='32' src='http://4.bp.blogspot.com/_SFBL69b3jRQ/TIUvCsYa5EI/AAAAAAAAACw/4H33zrk1nAI/S220/shades.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-37404288.post-1430111259199526908</id><published>2007-03-16T14:10:00.001+01:00</published><updated>2008-05-05T12:38:10.571+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Java'/><category scheme='http://www.blogger.com/atom/ns#' term='generics'/><category scheme='http://www.blogger.com/atom/ns#' term='functions'/><title type='text'>VList in Java</title><content type='html'>&lt;span style="font-size:85%;"&gt;&lt;span style="font-family:arial;"&gt;Two days ago I was reading &lt;a href="http://www.javalobby.org/java/forums/t91346.html"&gt;this article&lt;/a&gt; about LISP like lists implemented in Java, &lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:arial;"&gt;which reminded me I had written an implementation of a &lt;a href="http://en.wikipedia.org/wiki/VList"&gt;VList&lt;/a&gt; in Java. It can be found &lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:arial;"&gt;&lt;a href="http://ted.appspot.com/read/Java/Functional/collections/VList"&gt;here&lt;/a&gt;, along with &lt;a href="http://ted.appspot.com/read/Java/Functional/collections/VListTest"&gt;a unit test&lt;/a&gt;.I make no garantee this is the best or fastest implementation possible!&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:arial;"&gt;It implements: get(n), first (head in Haskell), rest() (tail in Haskell), size(), iterator() and map(Mapper), where Mapper is the mapping interface I mentioned earlier.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:arial;"&gt;It's using Java Generics of course. Am I right in thinking there is no way with Java generics to get rid of the compilation warnings and of the necessity of passing the Class object in the code that creates a new array of the generic type?&lt;/span&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/37404288-1430111259199526908?l=jpmoresmau.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jpmoresmau.blogspot.com/feeds/1430111259199526908/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=37404288&amp;postID=1430111259199526908' title='9 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/37404288/posts/default/1430111259199526908'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/37404288/posts/default/1430111259199526908'/><link rel='alternate' type='text/html' href='http://jpmoresmau.blogspot.com/2007/03/vlist-in-java.html' title='VList in Java'/><author><name>JP Moresmau</name><uri>http://www.blogger.com/profile/09964251063221757176</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='26' height='32' src='http://4.bp.blogspot.com/_SFBL69b3jRQ/TIUvCsYa5EI/AAAAAAAAACw/4H33zrk1nAI/S220/shades.jpg'/></author><thr:total>9</thr:total></entry><entry><id>tag:blogger.com,1999:blog-37404288.post-3574694022570938275</id><published>2007-03-09T15:55:00.000+01:00</published><updated>2007-03-09T15:59:43.298+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Java'/><category scheme='http://www.blogger.com/atom/ns#' term='properties'/><category scheme='http://www.blogger.com/atom/ns#' term='generics'/><title type='text'>Java properties with no language changes (oh no!)</title><content type='html'>&lt;span style="font-size:85%;"&gt;&lt;br /&gt;There's been a lot of discussions on the web about Java and the support for bean properties. People would like to have a mechanism that relies less on java bean conventions (reflection on method names, find getters and setters) and more on explicit language constructs. The goal is to simplify bean and property handling, have stronger type checks, be able to reference the property and not its values, etc... Most proposals involve additions to the Java syntax. I don't want to add to the confusion, but I just played around with what we have now in Java 5.&lt;br /&gt;What we could have is instead of defining classes directly with fields in them, we could have them reference Property objects instead. Property objects carry the type information and the value itself. An inheritance hierarchy can provide for read-only, write-only and read-write hierarchy. Using public final fields we can have an access syntax that is not the same as the current getter and setter methods, but pretty close.&lt;br /&gt;Example:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;public class PersonBean {&lt;br /&gt;    public final IFullProperty&lt;string&gt; name=new NonNullProperty&lt;string&gt;();&lt;br /&gt;   &lt;br /&gt;    public final IReadProperty&lt;integer&gt; id;&lt;br /&gt;   &lt;br /&gt;    public final IFullProperty&lt;string&gt; email=new FullProperty&lt;string&gt;(){&lt;br /&gt;        @Override&lt;br /&gt;        public void set(String value) {&lt;br /&gt;            if (value.indexOf('@')==-1){&lt;br /&gt;                throw new IllegalArgumentException("email does not contain @");&lt;br /&gt;            }&lt;br /&gt;            super.set(value);&lt;br /&gt;        }&lt;br /&gt;    };&lt;br /&gt;   &lt;br /&gt;    public PersonBean(int id,String name){&lt;br /&gt;        this.name.set(name);&lt;br /&gt;        this.id=new ReadOnlyProperty&lt;integer&gt;(id);&lt;br /&gt;    }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Of course, the generic madness means the type information has to be typed twice, but when generics syntax is cleaned up it'd be a lot more readable. This bean says that it has a changeable name property, a String that cannot be null. It has an id integer property that cannot be changed. Finally it has an email property that has ad hoc constraint checking. The Property interfaces and its sub interfaces define a get() and a set() method so accessing the fields becomes:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;bean.getName() -&gt; bean.name.get()&lt;br /&gt;bean.setName(name) -&gt; bean.name.set(name)&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;The property change listener can be attached to the property object so that the bean doesn't have to have any line of code related to listeners. Everything can be done via static methods:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;static void addPropertyChangeListener(Object bean,PropertyChangeListener pcl);&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;to add a listener on all properties&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;static void addPropertyChangeListener(Object bean,PropertyChangeListener pcl,IProperty&lt;?&gt; p);&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;to add a listener on a specific property. Note that since we're taking a property object, and not a property name for example we cannot register a listener on a non existing property. The property does not have a back link to its bean (to avoid disgracious constructors with this), so we need to have both the bean and the propert.&lt;br /&gt;Example:&lt;br /&gt;addPropertyChangeListener(bean,listener,bean.email)&lt;br /&gt;&lt;br /&gt;If anybody's interested, all the code with unit tests is available &lt;a href="http://www.moresmau.fr/jp/java/src/fr/moresmau/jp/props"&gt;here&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/37404288-3574694022570938275?l=jpmoresmau.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jpmoresmau.blogspot.com/feeds/3574694022570938275/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=37404288&amp;postID=3574694022570938275' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/37404288/posts/default/3574694022570938275'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/37404288/posts/default/3574694022570938275'/><link rel='alternate' type='text/html' href='http://jpmoresmau.blogspot.com/2007/03/java-properties-with-no-language.html' title='Java properties with no language changes (oh no!)'/><author><name>JP Moresmau</name><uri>http://www.blogger.com/profile/09964251063221757176</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='26' height='32' src='http://4.bp.blogspot.com/_SFBL69b3jRQ/TIUvCsYa5EI/AAAAAAAAACw/4H33zrk1nAI/S220/shades.jpg'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-37404288.post-3287833435851330742</id><published>2007-02-02T12:23:00.000+01:00</published><updated>2007-02-02T12:31:07.355+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='games'/><category scheme='http://www.blogger.com/atom/ns#' term='mazes'/><category scheme='http://www.blogger.com/atom/ns#' term='Flex'/><category scheme='http://www.blogger.com/atom/ns#' term='GUI'/><category scheme='http://www.blogger.com/atom/ns#' term='HGL'/><category scheme='http://www.blogger.com/atom/ns#' term='Haskell'/><category scheme='http://www.blogger.com/atom/ns#' term='functions'/><title type='text'>Haskell User Interface???</title><content type='html'>&lt;span style="font-size:85%;"&gt;It's been a long time since I've last posted, the fault to Christmas and holidays. In the meantime though I have done some more Haskell. I have used Prim's algorithms described &lt;a href="http://www.astrolog.org/labyrnth/algrithm.htm"&gt;here&lt;/a&gt; to generate a random maze. That forced me to use Random to generate the maze and HGL to display it, and allow the user to navigate from the entrance to the exit with direction keys. Works great, but I was looking at Haskell UIs to see what I could use, and there doesn't seem to be a &lt;a href="http://www.haskell.org/haskellwiki/Libraries_and_tools/GUI_libraries"&gt;consensus&lt;/a&gt; on a functional GUI library in Haskell. HGL is fairly low level and limited, wxwidgets ports have an imperative air about them and some of the ground breaking frameworks still seem to be experimental (and to be honest, I don't think I'm ready to deal with arrow-based frameworks yet, I'm still struggling with the monads...). So maybe the solution is elsewhere? I've seen in the Java world people talk about &lt;a href="http://www.flex.org/"&gt;Flex&lt;/a&gt;, has anybody done anything integrating a Flex front end with a Haskell back-end?&lt;br /&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/37404288-3287833435851330742?l=jpmoresmau.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jpmoresmau.blogspot.com/feeds/3287833435851330742/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=37404288&amp;postID=3287833435851330742' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/37404288/posts/default/3287833435851330742'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/37404288/posts/default/3287833435851330742'/><link rel='alternate' type='text/html' href='http://jpmoresmau.blogspot.com/2007/02/haskell-user-interface.html' title='Haskell User Interface???'/><author><name>JP Moresmau</name><uri>http://www.blogger.com/profile/09964251063221757176</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='26' height='32' src='http://4.bp.blogspot.com/_SFBL69b3jRQ/TIUvCsYa5EI/AAAAAAAAACw/4H33zrk1nAI/S220/shades.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-37404288.post-2085432511010302728</id><published>2006-12-15T13:53:00.000+01:00</published><updated>2006-12-15T14:02:25.771+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='parsing'/><category scheme='http://www.blogger.com/atom/ns#' term='Haskell'/><category scheme='http://www.blogger.com/atom/ns#' term='game'/><category scheme='http://www.blogger.com/atom/ns#' term='functions'/><title type='text'>Adventures in Haskell: the Parsec magic weapon</title><content type='html'>&lt;span style="font-size:85%;"&gt;&lt;span style="font-family:verdana;"&gt;Following &lt;a href="https://beta.blogger.com/comment.g?blogID=37404288&amp;amp;postID=4115526671767491276"&gt;suggestions&lt;/a&gt;, I have rewritten the parsing code using &lt;a href="http://www.cs.uu.nl/%7Edaan/parsec.html"&gt;Parsec&lt;/a&gt;. I have to say, it was a good experience. Not everything worked first time, but I feel the code is a lot clearer that doing everything myself line by line. I've compared the two source files: &lt;a href="http://www.moresmau.fr/jp/haskell/src/DataAdvParser.hs"&gt;DataAdvParser.hs&lt;/a&gt; and the new &lt;a href="http://www.moresmau.fr/jp/haskell/src/DataAdvParsec.hs"&gt;DataAdvParsec.hs&lt;/a&gt;. There's more lines in the Parsec based files because I've had problems with the normal Haskell layout, but the file is overall smaller. Moreover, I have discovered ambiguities and bugs in the initial version when I had to get Parsec to work properly. And of course looking at the Haskell code you actually understand the grammar of the input file...&lt;br /&gt;I don't feel at the moment I'm getting better in Haskell: using Parsec just meant using a library API but didn't mean much in terms of learning the language or the underlying technologies (monads, etc...). I'm thinking maybe writing a little DSL for my adventure game data would help, but I haven't yet found a good tutorial. Ideally I'd like to get to something that's similar to what's been done for HTML or SQL, but for a very simple language...&lt;br /&gt;Anyway, I'll see, next steps would be to write maybe an automated game world generator so that I could play a new game every time...&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/37404288-2085432511010302728?l=jpmoresmau.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jpmoresmau.blogspot.com/feeds/2085432511010302728/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=37404288&amp;postID=2085432511010302728' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/37404288/posts/default/2085432511010302728'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/37404288/posts/default/2085432511010302728'/><link rel='alternate' type='text/html' href='http://jpmoresmau.blogspot.com/2006/12/adventures-in-haskell-parsec-magic.html' title='Adventures in Haskell: the Parsec magic weapon'/><author><name>JP Moresmau</name><uri>http://www.blogger.com/profile/09964251063221757176</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='26' height='32' src='http://4.bp.blogspot.com/_SFBL69b3jRQ/TIUvCsYa5EI/AAAAAAAAACw/4H33zrk1nAI/S220/shades.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-37404288.post-3199202796166037201</id><published>2006-12-08T15:10:00.001+01:00</published><updated>2008-05-05T12:44:57.894+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Java'/><category scheme='http://www.blogger.com/atom/ns#' term='Haskell'/><category scheme='http://www.blogger.com/atom/ns#' term='functions'/><title type='text'>An infinite list in Java</title><content type='html'>&lt;span style="font-size:85%;"&gt;&lt;span style="font-family:verdana;"&gt;In Haskell you can define infinite lists by providing, for example, the arithmetical properties of a suite. Lazy evaluation means only the elements needed by the program are calculated. Now, I was looking at doing the same thing in Java, and there's not too much to it.&lt;br /&gt;An infinite list is an Iterable over a generic type (called E in my code). The base class is abstract, and you need to provide the implementation of a getNext() method, that provides the next element in the list. The list is backed by an ArrayList, so that values are only calculated once. There is of course no size() method, but the size of the underlying array list tells you how many elements have been calculated. Note that each calculated value being stored in memory, you cannot go too far in a list with this system. But hey, we're playing here.&lt;br /&gt;&lt;br /&gt;For example this is how you can implement the Fibonacci suite, using the code for InfiniteList &lt;a href="http://www.moresmau.fr/jp/java/src/fr/moresmau/jp/func/InfiniteList.java"&gt;here&lt;/a&gt;:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;InfiniteList&lt;integer&gt; il=new InfiniteList&lt;integer&gt;(){&lt;/integer&gt;&lt;/integer&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;    @Override&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;    protected Integer getNext() {&lt;br /&gt;&lt;/span&gt;&lt;span style="font-family:courier new;"&gt;        switch (this.getData().size()){&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;            case 0:return 1;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;            case 1:return 1;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;            default: return this.getData().get(this.getData().size()-1)+this.getData().get(this.getData().size()-2);&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;        }&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;    }    &lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;};&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;You then use the iterator() method to get all the results you need. Don't forget to stop at some stages. The getNext() method is called by the calculateNext() method on the base class:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;private void calculateNext(){&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;    E next=getNext();&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;    data.add(next);&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;}&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;which in turn is called by the ensureCalculated method, that checks that we have the value at a particular index:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;private void ensureCalculated(int index){&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;    while (index&gt;=data.size()){&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;        calculateNext();&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;    }&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;}&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;So the standard list get method becomes:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;public E get(int index) {&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;    if (index&lt;0){&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;        throw new IllegalArgumentException("index&lt;0");&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;    }&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;    ensureCalculated(index);&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;    return data.get(index);&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;}&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;You can then have the methods Haskell provide you, for example, take and map. Take returns a sublist made of the nth first elements of the list and map gives back another infinite list calculated from the first by applying a function to each element, as required. We can use the following interface:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;public interface Mapper&lt;e1,e2&gt; {&lt;/e1,e2&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;    E2 map(E1 initial);&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;}&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;And the map method is:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;public &lt;e2&gt; InfiniteList&lt;e2&gt; map(final Mapper&lt;e,e2&gt; mapper){&lt;/e,e2&gt;&lt;/e2&gt;&lt;/e2&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;    return new InfiniteList&lt;e2&gt;(){&lt;/e2&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;            &lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;        @Override&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;        protected E2 getNext() {&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;            return mapper.map(InfiniteList.this.get(getData().size()));&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;        }&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;    };&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;}&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;We can also have another infinite list that is a filtered list from the original, using the same interface as above with the E2 generic type a boolean. Watch out, though: if the filter returns false all the time, a call to next() might never return...&lt;br /&gt;&lt;br /&gt;The full code can be found &lt;a href="http://ted.appspot.com/read/Java/Functional/collections/InfiniteList"&gt;here&lt;/a&gt; for the InfiniteList class, &lt;a href="http://ted.appspot.com/read/Java/Functional/func/Mapper"&gt;here&lt;/a&gt; for the Mapper interface. Sample code in the form of unit tests are &lt;a href="http://ted.appspot.com/read/Java/Functional/collections/InfiniteListTest"&gt;here&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/37404288-3199202796166037201?l=jpmoresmau.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jpmoresmau.blogspot.com/feeds/3199202796166037201/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=37404288&amp;postID=3199202796166037201' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/37404288/posts/default/3199202796166037201'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/37404288/posts/default/3199202796166037201'/><link rel='alternate' type='text/html' href='http://jpmoresmau.blogspot.com/2006/12/in-haskell-you-can-define-infinite.html' title='An infinite list in Java'/><author><name>JP Moresmau</name><uri>http://www.blogger.com/profile/09964251063221757176</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='26' height='32' src='http://4.bp.blogspot.com/_SFBL69b3jRQ/TIUvCsYa5EI/AAAAAAAAACw/4H33zrk1nAI/S220/shades.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-37404288.post-4115526671767491276</id><published>2006-12-05T09:28:00.000+01:00</published><updated>2006-12-05T09:31:54.049+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Haskell'/><category scheme='http://www.blogger.com/atom/ns#' term='game'/><category scheme='http://www.blogger.com/atom/ns#' term='functions'/><title type='text'>Adventures in Haskell: parsing the game world</title><content type='html'>&lt;span style="font-size:85%;"&gt;It's been a while since my last post in Haskell, as it's hard to find the time when I spend 40 hours a week doing Java, and there's little people to take care of in the house... I have been working on my adventure game, still, mainly to separate the data from the actual code. After a fews days of tinkering, I have it working, yoohoo!&lt;br /&gt;Of course, having to write a simple parser was a bit challenging given my limited knowledge of the language, and I wanted to stay with simple constructs. Hence,&lt;br /&gt;I don't use any monadic stuff, I just read the data file and deal with a list of Strings, one String per line, having each method take the list and send back the remainder of list. Promise, I will look into a state monad! And I know there some advanced parsing techniques in Haskell, I mean, more advanced than reading lines and calling words on it...&lt;br /&gt;I had fun with lazy IO, as any newbie Haskell programmer: using getContents seemed sometimes not to give me any lines back, until I understood than evaluating the result after closing the file handle was not the smart way to do things...&lt;br /&gt;So much for the "once it compiles, it works" mantra that I was chanting last time: when parsing a file, the content matters, too, not only the code, so I had trouble solving all the unmatched pattern errors I got. I found GHC more helpful than Hugs for error messages: an error that got me scratching my head for a while in Hugs got solved as soon as I ran the same code in GHC.&lt;br /&gt;I tried as well Hugs.Observe to debug my program, but I fear my grasp of lazy evaluation is too limited yet: sometimes I was sure I was getting into a method but observe was not reporting anything...&lt;br /&gt;Anyway, if anybody is interested in the code, the parser code is &lt;a href="http://www.moresmau.fr/jp/haskell/src/DataAdvParser.hs"&gt;here&lt;/a&gt;, and an example of a data file is &lt;a href="http://www.moresmau.fr/jp/haskell/src/data.txt"&gt;here&lt;/a&gt;. The structure is simple enough, blank lines are used a separator and on most lines the first couple of words are keywords (item codes, location codes, etc...). The adapted game code is &lt;a href="http://www.moresmau.fr/jp/haskell/src/DataAdvGame.hs"&gt;here&lt;/a&gt; (note that the path to the data file is hard-coded here)&lt;br /&gt;As usual, any comments and suggestions welcome! &lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/37404288-4115526671767491276?l=jpmoresmau.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jpmoresmau.blogspot.com/feeds/4115526671767491276/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=37404288&amp;postID=4115526671767491276' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/37404288/posts/default/4115526671767491276'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/37404288/posts/default/4115526671767491276'/><link rel='alternate' type='text/html' href='http://jpmoresmau.blogspot.com/2006/12/adventures-in-haskell-parsing-game.html' title='Adventures in Haskell: parsing the game world'/><author><name>JP Moresmau</name><uri>http://www.blogger.com/profile/09964251063221757176</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='26' height='32' src='http://4.bp.blogspot.com/_SFBL69b3jRQ/TIUvCsYa5EI/AAAAAAAAACw/4H33zrk1nAI/S220/shades.jpg'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-37404288.post-1589134296804123434</id><published>2006-11-24T15:37:00.000+01:00</published><updated>2006-11-24T16:09:49.029+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='closures'/><category scheme='http://www.blogger.com/atom/ns#' term='Java'/><category scheme='http://www.blogger.com/atom/ns#' term='functions'/><category scheme='http://www.blogger.com/atom/ns#' term='annotations'/><title type='text'>Higher order functions in Java with an annotation processor factory</title><content type='html'>&lt;span style="color: rgb(0, 0, 0);font-size:85%;" &gt;I’m continuing my explorations of both Java 5 features like generics and annotations and of functional programming constructs. A lot of Java discussions on the web these days are about closures: writing quick anonymous methods without having to wrap them in a abstract class (think Runnable, Comparator, …). Now, closures can also be related to higher order functions, that is to say functions considered as objects in their own right. If you can reference a precise method inside an instance instead of just having to deal with interface, you can have a type of closures. For example, instead of passing a Comparator&lt;t&gt; object you could pass a Function&lt;integer,t,t&gt; object, meaning a function that takes two T arguments and returns an integer.&lt;br /&gt;To illustrate this point, let’s take an example.&lt;br /&gt;You have a simple Sale class:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;public class Sale {&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;    private String customer;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;    private Date dateOfSale;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;    private float amount;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;    &lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;    public Sale(String customer, Date dateOfSale, float amount) {&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;…constructor, getters and setters…&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;And you have a SaleManager class that encapsulates a list of sales (think retrieved from a database, etc…) and gives you a method to retrieve all sales sorted by what you want:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;public class SalesManagerClassic {&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;    private List&lt;sale&gt; sales;&lt;/sale&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;    &lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;    public SalesManagerClassic(List&lt;sale&gt; sales){&lt;/sale&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;        this.sales=sales;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;    }&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;    &lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;    public Sale[] listSales(Comparator&lt;sale&gt; comp){&lt;/sale&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;        Sale[] ret=new Sale[sales.size()];&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;        sales.toArray(ret);&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;        Arrays.sort(ret,comp);&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;        return ret;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;    }&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;    &lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;}&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;So far so good. Now you define a SaleComparator that will provide you all kinds of comparators:&lt;br /&gt;public class SaleComparatorClassic {&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;  public Comparator&lt;sale&gt; compareByCustomer(){&lt;/sale&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;        return new Comparator&lt;sale&gt;(){&lt;/sale&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;            public int compare(Sale o1, Sale o2) {&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;                return o1.getCustomer().compareToIgnoreCase(o2.getCustomer());&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;            }&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;        };&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;    }&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;    &lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;    public Comparator&lt;sale&gt; compareByAmount(){&lt;/sale&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;        return new Comparator&lt;sale&gt;(){&lt;/sale&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;            public int compare(Sale o1, Sale o2) {&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;                return (int) (o2.getAmount()-o1.getAmount());&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;            }&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;        };&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;    }&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;    &lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;}&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;As you can see, creating a comparator each time is tedious. Closure and higher order functions aim at simplifying the important code bits so that the actual strategy (how do we sort the sales) is not buried in all the boilerplate code. This is how we could use that class:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;List&lt;sale&gt; l=new ArrayList&lt;sale&gt;();&lt;/sale&gt;&lt;/sale&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;…&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;SalesManagerClassic smc=new SalesManagerClassic(l);&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;SaleComparatorClassic scc=new SaleComparatorClassic();&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;Sale[] s=smc.listSales(scc.compareByCustomer());&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;A Function object in Java is something like that, roughly:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;public abstract class Function {&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;    private Object instance;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;    &lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;    public Function(Object instance){&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;        this.instance=instance;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;    }&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;    &lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;    public Object getInstance() {&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;        return instance;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;    }&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;}&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;So it encapsulates the instance on which the function will be run. We’re not going out of the OO world right now.&lt;br /&gt;Then generics in Java do not (if they do, drop me a line) allow you to specify that a class can take any number of generic type in its definition, so we’ll have to define a concrete class for all possible numbers of parameters:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;public abstract class Function0&lt;r&gt; extends Function {&lt;/r&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;    public Function0(Object instance){&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;        super(instance);&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;    }&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;    &lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;    public abstract R run();&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;    &lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;}&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;The code above represents an object method that takes no argument and its return type is the generic type R (which could be Void if the method return nothing). Subclasses need to provide the actual implementation of the run method. And a function taking one parameter will be:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;public abstract class Function1&lt;r,p&gt; extends Function {&lt;/r,p&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;    public Function1(Object instance){&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;        super(instance);&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;    }&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;    &lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;    public abstract R run(P param);&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;    &lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;    public Function0&lt;r&gt; curry(final P param){&lt;/r&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;        Function0&lt;r&gt; f=new Function0&lt;r&gt;(getInstance()){&lt;/r&gt;&lt;/r&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;            @Override&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;            public R run() {&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;                return Function1.this.run(param);&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;            }&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;        };&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;        return f;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;    }&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;    &lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;}&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Here P is the type of the first parameter. For fun I added the curry function: if you know the first parameter but you don’t want to run the function right now, you can create a Function object with no argument that can be run later.&lt;br /&gt;&lt;br /&gt;So what would that mean for our sales manager? This is what the code can look like:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;public Sale[] listSales(final Function2&lt;integer,sale,sale&gt; func){&lt;/integer,sale,sale&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;    Sale[] ret=new Sale[sales.size()];&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;    sales.toArray(ret);&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;    Arrays.sort(ret,new Comparator&lt;sale&gt;(){&lt;/sale&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;        public int compare(Sale o1, Sale o2) {&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;            return func.run(o1, o2);&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;        }&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;    });&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;    return ret;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;}&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;The boiler plate for the comparator has been moved in one place (of course we still need it, we’re not writing our own version of Java where standard API calls takes our Function objects right now…). The Sale comparator is where the gain is made:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;@FunctionAnnotation&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;public int compareByCustomer(Sale o1,Sale o2){&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;    return o1.getCustomer().compareToIgnoreCase(o2.getCustomer());&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;}&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;    &lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;@FunctionAnnotation&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;public int compareByAmount(Sale o1,Sale o2){&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;    return (int) (o2.getAmount()-o1.getAmount());&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;}&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;The FunctionAnnotation is a simple method level annotation. This tells us: I want to be able to refer to these methods as Function objects. Note that my code for the moment does NOT deal with methods with the same name and different argument list. We’ll worry about that later… Notice for now how the methods are much simpler and how what they do is clear.&lt;br /&gt;&lt;br /&gt;Now, what we need to do, is to do automatically the translation between simple methods with the FunctionAnnotation and Function&lt;…&gt; objects that we can pass to our SalesManager. For this we’ll use an annotation process factory. This factory will run on the source code for SaleComparator, and will generate a SaleComparatorFunctions class that will have methods giving you the Function&lt;…&gt; objects:&lt;br /&gt;&lt;br /&gt; &lt;span style="font-family:courier new;"&gt;public static Function2&lt;integer,&gt; compareByAmount(final fr.moresmau.jp.func.samples.SaleComparatorFunctional instance){&lt;/integer,&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;        return new Function2&lt;integer,&gt; (instance){&lt;/integer,&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;            public Integer run(fr.moresmau.jp.func.samples.Sale param0, fr.moresmau.jp.func.samples.Sale param1) {&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;                return instance.compareByAmount( param0,  param1);&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;            }&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;  &lt;span style="font-family:courier new;"&gt;      };&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;    }&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;    public static Function2&lt;integer,&gt; compareByCustomer(final fr.moresmau.jp.func.samples.SaleComparatorFunctional instance){&lt;/integer,&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;        return new Function2&lt;integer,&gt; (instance){&lt;/integer,&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;            public Integer run(fr.moresmau.jp.func.samples.Sale param0, fr.moresmau.jp.func.samples.Sale param1) {&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;                return instance.compareByCustomer( param0,  param1);&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;            }&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;        };&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;    }&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Aren’t we happy this is generated for us ? Then we can just code our calls like that:&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;List&lt;sale&gt; l=new ArrayList&lt;sale&gt;();&lt;/sale&gt;&lt;/sale&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;…&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;SalesManagerFunctional smf=new SalesManagerFunctional(l);&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;SaleComparatorFunctional h=new SaleComparatorFunctional();&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;Sale[] s=smf.listSales(SaleComparatorFunctions.compareByCustomer(h));&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;That code is about the same complexity as before. Of course using another class for the function wrapping make the code not as clear as it should be. In a later post I’ll look at alternatives, so for the moment bear with me.&lt;br /&gt;&lt;br /&gt;So we have obtained higher order functions from a standard Java class, and we can use these functions instead of comparator objects.&lt;br /&gt;&lt;br /&gt;Now of course I haven’t talked about the annotation process factory yet. There’s nothing magic there. We need to implement an AnnotationProcessFactory and to say we want to do something when we encounter our annotation:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;public Collection&lt;string&gt; supportedAnnotationTypes() {&lt;/string&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;    return Arrays.asList("fr.moresmau.jp.func.FunctionAnnotation");&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;}&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;And we need to implement a AnnotationProcessor that will generate a &lt;classname&gt;Functions class for every class that as at least one method with the FunctionAnnotation. For that we need to use the createSourceFile method of the Filer object provided by the environment to create the function file.&lt;br /&gt;Running the factory is done through the JDK apt tool:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;apt -s src -factory fr.moresmau.jp.func.FunctionProcessorFactory -d bin -cp bin src/fr/moresmau/jp/func/samples/SaleComparator.java&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;The code for the Function objects and the AnnotationProcessFactory can be found &lt;a href="http://www.moresmau.fr/jp/java/src/fr/moresmau/jp/func"&gt;here&lt;/a&gt;, the Sale example &lt;a href="http://www.moresmau.fr/jp/java/src/fr/moresmau/jp/func/samples"&gt;here&lt;/a&gt;, with unit tests.&lt;br /&gt;&lt;br /&gt;&lt;/classname&gt;&lt;/integer,t,t&gt;&lt;/t&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/37404288-1589134296804123434?l=jpmoresmau.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jpmoresmau.blogspot.com/feeds/1589134296804123434/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=37404288&amp;postID=1589134296804123434' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/37404288/posts/default/1589134296804123434'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/37404288/posts/default/1589134296804123434'/><link rel='alternate' type='text/html' href='http://jpmoresmau.blogspot.com/2006/11/higher-order-functions-in-java-with.html' title='Higher order functions in Java with an annotation processor factory'/><author><name>JP Moresmau</name><uri>http://www.blogger.com/profile/09964251063221757176</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='26' height='32' src='http://4.bp.blogspot.com/_SFBL69b3jRQ/TIUvCsYa5EI/AAAAAAAAACw/4H33zrk1nAI/S220/shades.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-37404288.post-116375486398901334</id><published>2006-11-17T10:03:00.002+01:00</published><updated>2008-07-28T17:09:47.761+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Java'/><category scheme='http://www.blogger.com/atom/ns#' term='Design By Contract'/><category scheme='http://www.blogger.com/atom/ns#' term='Aspects'/><category scheme='http://www.blogger.com/atom/ns#' term='scripting'/><category scheme='http://www.blogger.com/atom/ns#' term='annotations'/><title type='text'>Design By Contract in Java using Annotations, Scripting and Aspects</title><content type='html'>&lt;span style="font-size:85%;"&gt;When you write a Java interface, you define a contract. This contract is made of methods and their signatures. Then, in the implementation code, you can write statements to check that the input parameters are not null, that return values are within a correct range, etc. The problem there of course is that if the implementation doesn't do these checks, or not properly, bugs&lt;br /&gt;may creep in and they may be hard to find. "&lt;a href="http://archive.eiffel.com/doc/manuals/technology/contract/"&gt;Design by Contract&lt;/a&gt;" is a set of techniques that&lt;br /&gt;let you specify conditions on method parameters, return values, etc, in such a way that they&lt;br /&gt;can be associated with interfaces and that the execution of these statements is assured by the&lt;br /&gt;runtime system, freeing the developer from the tedious tasks of throwing&lt;br /&gt;IllegalArgumentExceptions or assertions.&lt;br /&gt;&lt;br /&gt;To implement such techniques, you can use some off the shelf frameworks, like &lt;a href="http://jcontractor.sourceforge.net/doc/crashcourse.html"&gt;jContractor&lt;/a&gt;, but it's easy to roll out your own. You need only three components:&lt;br /&gt;&lt;/span&gt;&lt;ul&gt;&lt;li&gt;&lt;span style="font-size:85%;"&gt;you need to be able to attach conditions to classes and methods, without cluttering the code. For this, Java annotations are perfect&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-size:85%;"&gt;since we're not in Java code proper, we need a way to run our conditions, so we need a language for them. Well, why have another language, just use a Java scripting languages like &lt;a href="http://www.beanshell.org/"&gt;Beanshell&lt;/a&gt;. &lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-size:85%;"&gt;finally, the Beanshell code needs to be evaluated at runtime before or after methods calls. This is what aspect are for, right? We'll use &lt;a href="http://www.eclipse.org/aspectj/"&gt;AspectJ&lt;/a&gt; for that.&lt;/span&gt;&lt;/li&gt;&lt;/ul&gt;&lt;span style="font-size:85%;"&gt;&lt;br /&gt;So, let's see a concrete example. Suppose we implement a Stack (yeah, right, I don't have a lamer example).&lt;br /&gt;We start with the push method:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;public interface IStack&lt;t&gt; {&lt;/t&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;        void push(T o);&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;}&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Ok, but we don't like to have null values in this stack. So we want to specify in the interface definition that the first parameter cannot be null:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;@ContractMethodAnnotation (&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;        pre = {"p0!=null"}&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;    )&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;void push(T o);&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;We cannot access the names of the method parameters at runtime, so we use a simple convention: p0 is the first parameter, etc. You can also define post conditions that can access the return value using the name "return".&lt;br /&gt;&lt;br /&gt;Notice that we specify conditions on the interface, but that we will want the checks to apply to all its implementations.&lt;br /&gt;&lt;br /&gt;Conditions can access methods and variables of the class you define them on, but be careful, it's easy to create circular references where two method call each other:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;    boolean isEmpty();&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;    &lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;    @ContractMethodAnnotation (&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;            post = {"result&gt;=0"}&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;        )&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;    int size();&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;    &lt;/span&gt;&lt;br /&gt;It would be tempting to define a condition that isEmpty is true if size()==0 and that size()==0 if isEmpty is true... What you can do is define a class invariant condition: a condition that is always true of an object (even if it can transiently be false, it is true before and after public method invocation).&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;@ContractClassAnnotation (&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;        invariants={"(isEmpty() &amp;amp;&amp;amp; size()==0) || (!isEmpty() &amp;amp;&amp;amp; size()&gt;0)"}&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;    )&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;public interface IStack&lt;t&gt; { ... }&lt;/t&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;The implementation of the aspect is not very complicated. We define pointcuts for public methods that will check class invariants and for annotated methods that will check pre and post conditions. We use the BeanShell Interpreter object to parse and run the condition code. Thanks to the importObject Beanshell command we can run the code as if all methods referenced by the annotation code referenced the current instance.&lt;br /&gt;&lt;br /&gt;When we encounter a failure, we can either use an assertion or throw a RuntimeException.&lt;br /&gt;This can be set through the ContractAspect.setUseAsserts method. For fun, I have defined a way to set it through a bean shell configuration file, that is loaded by another aspect, that executes when the ContractAspect is statically initialized.&lt;br /&gt;&lt;br /&gt;The code can be found here: &lt;a href="http://ted.appspot.com/read/Java/DynamicContract/ContractAspect.aj"&gt;ContractAspect.aj&lt;/a&gt; is the aspect implementation, &lt;a href="http://ted.appspot.com/read/Java/DynamicContract/ContractClassAnnotation.java"&gt;ContractClassAnnotation.java&lt;/a&gt; and &lt;a href="http://ted.appspot.com/read/Java/DynamicContract/ContractMethodAnnotation.java"&gt;ContractMethodAnnotation.java&lt;/a&gt; are the definition of the annotations. &lt;a href="http://ted.appspot.com/read/Java/DynamicContract/SettingsAspect.aj"&gt;SettingsAspect.aj&lt;/a&gt; is the aspect that reads the configuration file and turn assertions on or off. An example of a configuration file is &lt;a href="http://www.blogger.com/DynamicContract/settings.bsh"&gt;here&lt;/a&gt;. As you see, it's only one line of Java code.&lt;br /&gt;&lt;br /&gt;The Stack example can be found &lt;a href="http://ted.appspot.com/read/Java/DynamicContract/samples/IStack.java"&gt;here&lt;/a&gt;, with an &lt;a href="http://ted.appspot.com/read/Java/DynamicContract/samples/StackImpl.java"&gt;implementation&lt;/a&gt; and a &lt;a href="http://ted.appspot.com/read/Java/DynamicContract/samples/StackTest.java"&gt;unit test&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/37404288-116375486398901334?l=jpmoresmau.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jpmoresmau.blogspot.com/feeds/116375486398901334/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=37404288&amp;postID=116375486398901334' title='6 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/37404288/posts/default/116375486398901334'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/37404288/posts/default/116375486398901334'/><link rel='alternate' type='text/html' href='http://jpmoresmau.blogspot.com/2006/11/design-by-contract-in-java-using.html' title='Design By Contract in Java using Annotations, Scripting and Aspects'/><author><name>JP Moresmau</name><uri>http://www.blogger.com/profile/09964251063221757176</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='26' height='32' src='http://4.bp.blogspot.com/_SFBL69b3jRQ/TIUvCsYa5EI/AAAAAAAAACw/4H33zrk1nAI/S220/shades.jpg'/></author><thr:total>6</thr:total></entry><entry><id>tag:blogger.com,1999:blog-37404288.post-116317311096564164</id><published>2006-11-10T16:36:00.001+01:00</published><updated>2009-04-09T16:01:36.004+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Haskell'/><category scheme='http://www.blogger.com/atom/ns#' term='game'/><category scheme='http://www.blogger.com/atom/ns#' term='functions'/><title type='text'>My first Haskell adventure game!</title><content type='html'>&lt;span style="font-size:85%;"&gt;After years of coding mainly in Java, I have taken the plunge and looked&lt;br /&gt;into a pure functional language. Haskell is quite popular these days, so I decided to read a book&lt;br /&gt;on it and play around with it myself.&lt;br /&gt;I got a bit frustrated at the maths or geometry examples, when I got to this great article &lt;a href="http://www.lisperati.com/casting.html"&gt;Casting spels in LISP &lt;/a&gt;that uses the medium of a text based adventure game to teach the basic notions of LISP.&lt;br /&gt;So I coded a very little (400 lines with data and documentation) text-based game in Haskell.&lt;br /&gt;The code can be found &lt;a href="http://ted.appspot.com/read/Haskell/AdventureGame.hs"&gt;here&lt;/a&gt; (You need a little extra module found &lt;a href="http://ted.appspot.com/read/Haskell/Utils.hs"&gt;here&lt;/a&gt;). In my enthusiasm I even added some Haddock documentation &lt;a href="http://ted.appspot.com/read/HTML/AdventureGame.html"&gt;here&lt;/a&gt;.&lt;br /&gt;The main features are:&lt;br /&gt;- use of the IO monad to get user input and give back feedback&lt;br /&gt;- use of the IO monad to save and load gaves&lt;br /&gt;- use of the Data.Map structure&lt;br /&gt;- use of the Show and Read classes to serialize and deserialize a Map structure&lt;br /&gt;- pure functional handling of state: every change in the game state recreates an instance of the&lt;br /&gt;GameState object. Yes, one day I'll look into the State monad to simplify these functions&lt;br /&gt;&lt;br /&gt;My first impressions of Haskell:&lt;br /&gt;- the syntax is quite hard to grasp, with loads of different signs. The indenting drove me mad sometimes.&lt;br /&gt;- thanks for the static typing and the compilation. I found that the hardest part was to get the program to compile.&lt;br /&gt;Once the program compiled all right it usually worked as intended.&lt;br /&gt;- I know that pattern matching and guards are only syntaxic sugar for case statements, but I found them (the patterns, the guards) a lot more elegant and easy to understand&lt;br /&gt;- I need to learn how to deal better with "newtype" and pattern matching. I used "newtype" instead of type for some data types because I needed to declare them as instances of Show and Read, but that forced me to use as-patterns for game state.&lt;br /&gt;Surely there's simpler ways to do that&lt;br /&gt;- yes, I know about $ to avoid parenthesis for function parameters, but with a good editor it's ok to manage&lt;br /&gt;&lt;br /&gt;Now, if anybody has tips on how to improve the code I'll take them on board. I'm going to look at separating the data from the code, maybe with a simple DSL and parser. And yes, the state or IORef monads... &lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/37404288-116317311096564164?l=jpmoresmau.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jpmoresmau.blogspot.com/feeds/116317311096564164/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=37404288&amp;postID=116317311096564164' title='12 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/37404288/posts/default/116317311096564164'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/37404288/posts/default/116317311096564164'/><link rel='alternate' type='text/html' href='http://jpmoresmau.blogspot.com/2006/11/my-first-haskell-adventure-game.html' title='My first Haskell adventure game!'/><author><name>JP Moresmau</name><uri>http://www.blogger.com/profile/09964251063221757176</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='26' height='32' src='http://4.bp.blogspot.com/_SFBL69b3jRQ/TIUvCsYa5EI/AAAAAAAAACw/4H33zrk1nAI/S220/shades.jpg'/></author><thr:total>12</thr:total></entry></feed>
