In this blog I talk about some of the personal programming I do as a hobby. From Java to Rust via Haskell, I've played around with a lot of technologies and still try to have fun with new languages and APIs!
Friday, October 07, 2011
New backend for EclipseFP
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.
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).
We only use the GHC API 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!).
Buildwrapper uses haskell-src-exts for outline. I've actually seen cases where it needed language pragmas to parse correctly that GHC didn't need, but such is life.
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.
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.
If people want to start testing, just go on github, and grab the BuildWrapper repository (main branch) and the EclipseFP project (buildwrapper branch). 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.
Friday, September 02, 2011
EclipseFP 2.1.0 released!
- A package/module browser
- Hoogle integration
- Support for running tests
- HLint warnings
- Support for running executables and get profiling graphs
- SourceGraph generation
- Better auto completion information
Lots, I'm telling you. There are also fixes and internal enhancements that hopefully should make your life easier.
You can just run the update from your Eclipse IDE. You can find the full release notes there.
Note that Alejandro has also created a new web site for EclipseFP, that you can find there. Alejandro, big thanks for your hard work and your dedication!
Any feedback is welcome, and of course bug reports and requests for enhancements!
Happy Haskell hacking in Eclipse!
Wednesday, August 31, 2011
Hoogle Command Line on Windows
The new upcoming version of EclipseFP will feature Hoogle integration, thanks to the work of Alejandro Serrano, 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.
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:
wget: http://gnuwin32.sourceforge.net/packages/wget.htm
At time of writing, the download page is http://sourceforge.net/projects/gnuwin32/files/wget/1.11.4-1/wget-1.11.4-1-setup.exe/download
gzip: http://gnuwin32.sourceforge.net/packages/gzip.htm
At time of writing, the download page is http://sourceforge.net/projects/gnuwin32/files/gzip/1.3.12-1/gzip-1.3.12-1-setup.exe/download
tar: http://gnuwin32.sourceforge.net/packages/gtar.htm
At time of writing, the download page is http://sourceforge.net/projects/gnuwin32/files/tar/1.13-1/tar-1.13-1-bin.exe/download
Install everything in the same directory and put the bin subdirectory in your PATH. hoogle data should run fine.
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 etc\wgetrc in the directory you installed wget, find the http_proxy entry and adapt to your settings.
Friday, June 24, 2011
EclipseFP: the way forward??
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.
Maybe more critically, people are now asking for features that get increasingly harder to implement using Scion:
- static GHC flags like -threaded (Nominolo's working on a version of Scion that could handle these)
- C or HSC sources (or other kind of stuff requiring a preprocessor)
- Having executables or test suites referencing the library component directly in the Cabal file
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...
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...
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.
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:
- create a temp folder in which we will work, copy in it all the project files (sources, etc)
- use cabal to build in that folder
- parse cabal output to get errors and their location
- 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)
- 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
- the IDE code then gets the AST and does all it needs to it
- 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)
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...
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!
Sunday, May 22, 2011
Haskell + FFI + Java + SWT: crazy, maybe, but working!
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
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.
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.
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:
- The Haskell applications starts as they all do, in a main :: IO() function
- 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
- Haskell uses the foreign C functions to create ands manipulate the SWT Java objects
- 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.
And I have proof! Here's a simple SWT Shell with one button:
When you click the button:
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):
do
modifyMVar count (\c->do
let nc=c+1
let s=if nc==1 then "once." else ((show nc)++ " times.")
text3<-toJString ("Clicked "++s)
voidMethod button "setText" "(Ljava/lang/String;)V" [JObj text3]
return(nc,())
)
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.
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...
Monday, April 18, 2011
Pirates 0.2: fixes and a chat interface
- Fixes in the collision detection code
- A chat interface, so you can talk to the other ship you're fighting with. Stock up on pirates insults!
- Fixes in handling of games when a ship leaves the game before it's finished
Friday, April 08, 2011
Pirates!! A multi-player browser game with Yesod and Canvas
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.
The technology stack is as follows:
- 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!
- Server side is Yesod 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).
- Client side uses Canvas with a sprinkling of JQuery.
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...
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!
I'm not too sure if I chose the best route for concurrency. I use MVars and modifyMVar.
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.
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 Michel Brassinne (French warning!). Thanks!
Still it was fun to do!! Hope you enjoy playing it a little!
Friday, April 01, 2011
Install GHC7 and Yesod on Amazon Linux
The free AMIs (images) come with a version of Linux specific to Amazon, but apparently binary compatible with CentOS, on which GHC and the Haskell Platform have been reported to successfully build.
These are the steps I followed to get everything working, hopefully they can be useful to somebody else. So as per the Amazon Getting Started guide, you connect to your instance with the ec2-user.
First we install through the package manager some useful packages:
sudo yum install make
sudo yum install gcc
sudo yum install zlib-devel
sudo yum install glut
sudo yum install glut-devel
I didn't find gmp, so I downloaded and installed in the default location:
curl -O ftp://ftp.gnu.org/gnu/gmp/gmp-4.3.2.tar.bz2
tar -xjvf gmp-4.3.2.tar.bz2
cd gmp-4.3.2
./configure
make
sudo make install
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:
sudo cp /usr/local/lib/libgmp.* /usr/lib/
But I suppose ./configure --prefix=/usr/lib/ would be the preferred way to do that.
Libbsd is also required otherwise unix-compat fails:
curl -O http://libbsd.freedesktop.org/releases/libbsd-0.2.0.tar.gz
tar -xzvf libbsd-0.2.0.tar.gz
cd libbsd-0.2.0
sudo make install
Then for GHC, I just downloaded the generic binary and installed that. I decided to install Haskell under my home folder.
curl -O http://haskell.org/ghc/dist/7.0.2/ghc-7.0.2-i386-unknown-linux.tar.bz2
tar -xjvf ghc-7.0.2-i386-unknown-linux.tar.bz2
cd ghc-7.0.2
./configure --prefix=/home/ec2-user/haskell
make install
Make sure we know how to find it:
export PATH=$PATH:/home/ec2-user/haskell/bin
Then get the Haskell Platform source and build that, since there is no binary (yet) for our platform:
curl -O http://lambda.galois.com/hp-tmp/2011.2.0.0/haskell-platform-2011.2.0.0.tar.gz
tar -xzvf haskell-platform-2011.2.0.0.tar.gz
cd haskell-platform-2011.2.0.0
./configure --prefix=/home/ec2-user/haskell
make
make install
Once you're there, it's back to familiar ground:
cabal update
cabal install yesod
And there we are!! My deployment platform is ready!
Monday, March 21, 2011
EclipseFP 2.0.4 released: supports GHC 7!
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).
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.
As usual, just install from the Eclipse update site: http://eclipsefp.sf.net/updates, and bug reports or feature requests should go to the SourceForge forum or the development mailing list.
Happy Haskell Hacking!
Monday, March 07, 2011
EclipseFP 2.0.3 released
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).
EclipseFP is alive and well (I use it for all my Haskell work) so please send us all your feedback, bug reports, feature requests!
Use the standard Eclipse Updates Site or download files. Enjoy!
Friday, January 21, 2011
Evolving a computer with TECS and Genprog
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 new genetic programming library on an Haskell group. Surely generating the gates would be simple enough?
So I got genprog from hackage, and adapted the example for my needs. I started with a very simple system to determine the implementation of Not:
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...)
Now, I'm going to see if this approach can take me all the way to the arithmetic unit...
Wednesday, December 01, 2010
EclipseFP 2.0.2 released
The release notes are here. To install or upgrade, just point your Eclipse to http://eclipsefp.sf.net/updates. Be sure to configure both the GHC path and the Cabal path in the preferences.
Happy Haskell hacking!
Thursday, November 25, 2010
A simple game in Haskell + SDL
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 LIBS=/usr/local/lib/libSDL_ttf.dll.a in my MSYS environment then configure worked fine!
Afterwards it was all plain sailing, really. Just remember to add enableUnicode True 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 GNU FreeFont file with the package. It needs to be in the same folder as the executable.
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 MVar 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.
This brilliant piece of software that has already made its mark in video game history can be found on Hackage here!
As usual, all feedback is welcome. Possible enhancements are a high score screen, difficulty levels, choosing letters by frequency in English, using Markov chains so that the flow of letters look more natural... The list is infinite!
Thursday, September 30, 2010
EclipseFP 2.0.0 released!
I'm proud to announce version 2.0.0 of EclipseFP, 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:
- the Antlr parsing has been removed
- the JFace based syntax highlighter has been removed
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.
Also, we now communicate to the Scion library via standard streams instead of network calls, which should solve some headaches.
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 here.
Another good news is that I'm not alone in hacking at EclipseFP, scooter 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!
Just point your Eclipse to the EclipseFP update site, and happy Haskell hacking!!
Friday, September 24, 2010
Haskell Neural Network: plugging a space leak
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!
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 some files. 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!
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 ! (BangPatterns is your friend) didn't help any more. WTF?
Then I started to read a bit more about seq and Weak Head Normal Form. 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 deepseq 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:
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...
Friday, September 17, 2010
Digit recognition with a neural network. First attempt!
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.
The input will be a list of 25 numbers, either 0 (off) or 1 (on)
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).
I arbitrarily decide to set the number of hidden neurons to 50, twice the input neurons. So my topology is 25-50-10.
I train the network with only one version of each digit. For example 3 would be:
*****
*
****
*
*****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]).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).
Then the real test: can my network recognize small variants of the training set?
Lets's try with:
****
*
***
*
****(a slightly rounded 3): the network answers 3!!Works also for a slightly rounded 6. But then:
*** * * *** * * ***(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:
*** * * ***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).
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).
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...
Monday, September 06, 2010
EclipseFP development: using the GHC Lexer
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 GHC Lexer 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.
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 AttoJson, 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.
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 all the lexer flags, since performance didn't seem to suffer. Be liberal in what you parse...
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.
So don't worry, EclipseFP is coming soon!
Wednesday, June 02, 2010
EclipseFP 1.111 released
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.
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!
Friday, May 28, 2010
Gtk2hs and Leksah on Windows, check!
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!
Wednesday, May 05, 2010
Haskell SDL on Windows, check! (hacking required)
rawSystemL ("linking " ++ oProgName) beVerbose linker
( [f | LinkFlag f <- flags]
++ [oProgName]
++ ["-o", progName]
) rawSystemL ("linking " ++ oProgName) beVerbose linker
( [oProgName]
++ [f | LinkFlag f <- flags]
++ ["-o", progName]
)Friday, April 30, 2010
Happstack on Window, check! (in a long, round-about, fear-inducing way)
Wednesday, April 28, 2010
WXWidgets and WxHaskell on Windows, check!
set PATH=c:\dev\MinGW\bin;c:\dev\MinGW\libexec\gcc\mingw32\3.4.5;%PATH%
mingw32-make -f makefile.gcc BUILD=debug
set WXWIN=c:\ui\wxWidgets-2.8.10
set WXCFG=gcc_dll\mswud
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
Thursday, April 22, 2010
The sorry plight of a Windows programmer (aka me)
Friday, April 09, 2010
Found my neural network bug (three years later)
Thursday, February 11, 2010
Waterloo Contest and Human Intelligence
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 (-:
Monday, February 01, 2010
EclipseFP 1.110 released, with debugging support
I have released a new version of EclipseFP. OK, I haven't kept to the one-release-a-month schedule, but with the Christmas season and everything, I deserved a break.
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.
I have mainly worked at integrating the GHCi debugger with the Eclipse debugging framework. This tutorial 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 :step) 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 :show bindings, etc.
I have removed some obsolete preferences and added debugging preferences (stop on error/exception, use show instances...).
I'll be happy with any feedback on all these features. One thing missing is support for :hist when invoking :trace, tell me if you'd like that.
Enjoy!
Monday, November 23, 2009
EclipseFP 1.109.0 is out!
On a related note, I read that in "Coders at Work" Simon Peyton-Jones 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...
Friday, October 23, 2009
Releasing my code on the unsuspecting public (EclipseFP)
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 game 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...
Anyway, I hope I'll get some feedback on the new EclipseFP, and that we can move that thing forward!
Friday, October 09, 2009
What client for an Haskell Multi Player Game?
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 web sockets 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.
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 OpenGL in Haskell, and do everything in Haskell instead of mixing Haskell with HTML and JavaScript (I've just stumbled upon jmacro, which could be cool I guess).
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.
Monday, September 28, 2009
Haskell development in Eclipse
EclipseFP has had a troubled history so far. Leif 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 Thomas started integrating with Scion, 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.
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.
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.
For those interested, the github repositories where my current work can be found are:
git://github.com/JPMoresmau/scion.git
git://github.com/JPMoresmau/eclipsefp.git
Friday, August 07, 2009
Yoohoo: mazes of monad is kind of popular!
Friday, July 10, 2009
Mazes of Monad: 1.0.5 and (maybe) final version uploaded
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...
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 happstack as the server (or should I just use a little home grown server in Haskell, for fun?). I'll keep on posting about that!
Friday, May 15, 2009
Adding a Writer Monad transformer
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:
myFunction :: Type1 -> Type2 -> (Type3,[String])
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
WriterT a (RandT (StateT b IO)) c
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.
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:
myFunction :: (MonadWriter [String] m)=>Type1 -> Type2 -> m Type3
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:
myFunction :: (MonadRandom m, MonadWriter [String] m)=>Type1 -> Type2 -> m Type3
and I get random numbers capabilities!
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...
Monday, April 27, 2009
Haskell RPG Game uploaded on Hackage!
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.
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.
There are a few HUnit tests to verify that the most basic functionality works, so hopefully there is no huge bug.
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...).
Any feedback on the game mechanism or on the code itself is welcome!
Friday, February 27, 2009
A high-level GUI library for Haskell
The ideas being my own library, tentatively called UITree are the following:
- you build your GUI using combinators that start from simple widgets and use composite widgets and layouts to augment a tree
- event handler can be attached to widgets in the tree. The handlers are of type (ui, state)->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.
- inside the event handlers you manipulate the ui tree a bit like JQuery 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.
- 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).
For the moment I got some small samples to work with WXWidgets (Barrie uses GTK, by the way).
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:
simpleState :: IO (Int)
simpleState=do
start simpleUI 0 -- start the WXWidgets UI with the given UI tree and initial state
where
simpleUI=(frame [text := "Simple"]) -- the enclosing frame
(
(panel []) -- a panel to enclose our children
(row [space := 5] -- children in a row, a bit of space
[
(button [text := "0"] [command :> (return . doInc)]), -- a button showing 0 and increasing the state when clicked
(button [wid:="close", text := "Close!"] [command :> (pureUI doClose)]) -- a button to close the frame, pureUI is just a helper function that shows we're not modifying the state
]
)
)
doInc (tree,st)=(set [text := (show (st+1))] tree,(st+1)) -- set the button text and state to state + 1
doClose tree=close $ top tree -- close the top of the tree (the frame)
Note how the ui building and the handlers are pure functions, so you just manipulate your tree and your state.
Friday, November 28, 2008
Predictable random for testing
However for writing unit tests 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
want to clutter the code (even if using a State monad) with something used only for testing, so I experimented with IORef and a custom Test Generator.
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
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
dice throws:
data TestGen = TestGen [Int] Int
mkTestGen is just a helper function to initialise the index to 0
mkTestGen l=TestGen l 0
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,
if somewhat of a kludge:
testGen :: IORef (TestGen)
{-# NOINLINE testGen #-}
testGen=unsafePerformIO (newIORef (mkTestGen []))
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
without the NOINLINE pragma. Don't ask me why. So, given a simple setter function:
setTestGen l=do
writeIORef testGen (mkTestGen l)
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
in the list, and increment the index, going back to zero if we overrun the list:
randomInt ::(Int,Int) -> IO (Int)
randomInt (l,h)=do
(TestGen list ix)<-readIORef testGen
if null list
then getStdRandom (randomR (l,h))
else do
let e=list!!ix
let ix'=ix+1
let ix''=if ix'==(length list)
then 0
else ix'
writeIORef testGen (TestGen list ix'')
if e<l || e>h
then error (printf "%d not in range (%d,%d)" e l h)
else return e
And this works, amazingly:
setTestGen [2]
l<-replicateM 3 (randomInt (1,6))
assertEqual ("l is not 3 2s") [2,2,2] l
setTestGen [2,3,4]
l<-replicateM 4 (randomInt (1,6))
assertEqual ("l is not 2,3,4,2") [2,3,4,2] l
setTestGen []
(Notice how I reset the test generator to standard at the end by passing an empty list).
So now I can test my code with predictable results, that will be still random in production use.
Oops, already found a bug on the first test written with that technique!
Monday, November 03, 2008
Haskell for counting votes!
No pesky elephant vs donkey, here, the election is about your favorite female movie star:
data Star = MarylinMonroe | AngelinaJolie | BrigitteBardot | EmmanuelleBeart | ClaudiaCardinale
deriving (Show,Read,Eq,Bounded,Enum,Ord,Ix)
Note the "deriving Ix" (from Data.Array.IArray) so we can use the stars as array indices.
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:
votes :: [(Double,[Star])]
votes = [
(7.2,[MarylinMonroe,EmmanuelleBeart,ClaudiaCardinale,BrigitteBardot,AngelinaJolie]),
(4.8,[AngelinaJolie,ClaudiaCardinale,EmmanuelleBeart,BrigitteBardot,MarylinMonroe]),
(4,[BrigitteBardot,AngelinaJolie,ClaudiaCardinale,EmmanuelleBeart,MarylinMonroe]),
(3.6,[EmmanuelleBeart,BrigitteBardot,ClaudiaCardinale,AngelinaJolie,MarylinMonroe]),
(1.6,[ClaudiaCardinale,AngelinaJolie,EmmanuelleBeart,BrigitteBardot,MarylinMonroe]),
(0.8,[ClaudiaCardinale,BrigitteBardot,EmmanuelleBeart,AngelinaJolie,MarylinMonroe])
]
With this we need a few helper method before we're ready to implement our voting algorithms.
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
accumVotes :: [(Star,Double)] -> [(Star,Double)]
accumVotes v=let
arr=(accumArray (+) 0 (MarylinMonroe,ClaudiaCardinale) v):: Array Star Double
in sortBy (\a b -> compare (snd b) (snd a)) (assocs arr)
For some reason I needed to tell GHC about the array type, it couldn't infer it.
We need a way to get the votes for a given round (even if we'll only be using the first round this way)
roundResults :: Int -> [(Star,Double)]
roundResults r=let
v=map (\(a,b)->(b !! r,a)) votes
in accumVotes v
And a simple extraction function to get the winner's name from accumulated votes:
bestVote ::[(Star,Double)] -> Star
bestVote v= fst $ head $ (accumVotes v)
Now we're ready. The first algorith is a simple one round voting election:
oneRound :: Star
oneRound=bestVote (roundResults 0)
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:
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?)
findFirst :: Eq a => [a] -> [a] -> a
findFirst toFind (a:rest) = if elem a toFind
then a
else findFirst toFind rest
Then it's straightforward: we get the first two candidates after the first round, and accumulate their results over all the profiles
twoRounds :: Star
twoRounds= let
(fr1:fr2:_)=(roundResults 0)
allScores=map (\(a,b)->(findFirst [fst fr1,fst fr2] b,a)) votes
in bestVote allScores
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:
elimination :: Star
elimination= fst $ elimination' (roundResults 0)
where
elimination' :: [(Star,Double)] -> (Star,Double)
elimination' (a:b:[])=a
elimination' l= let
firstRound= map fst $ init l
in elimination' $ filter (\a->(snd a) >0.0 ) $ accumVotes $ map (\(a,b)->(findFirst firstRound b,a)) votes
This little recursivity yields Brigitte Bardot. Borda 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.
borda :: Star
borda = bestVote $ concat $ map (\(a,ss)-> map (\(s,mul)->(s,mul*a)) (zip ss [5,4 .. 1])) votes
And this time, Emanuelle Béart comes on top! Last method we will survey is from Condorcet: 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:
condorcet :: Star
condorcet= let
matches=[[x,y] | x <-allStars, y <- tail [x .. ClaudiaCardinale]]
matchResults= map (\match->(bestVote $ map (\(a,b)->(findFirst match b,a)) votes,1)) matches
in bestVote matchResults
And, behold, the winner through this method is... Claudia Cardinale! Five methods, five winners!
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!

