Skip navigation

It’s been quite a while (a month, actually) since my last post. That is not a sign of laziness, however, on the contrary; I’ve been busy playing around with Haskell and Python lately. In the last post I wrote about taking a break from Ogre to see what this thing called functional programming actually means. I think I’ve come closer to figuring that out in the past month.

Haskell really is quite an interesting language. (There’s a little tutorial showing some very nice aspects about Haskell here.) I started learning it by going through the tutorials available at haskell.org, and especially walking through Yet Another Haskell Tutorial, a mighty PDF book that explains all the major aspects of the language. I really had problems figuring out how to simulate state within Haskell, and the State monad didn’t really make it seem much easier. After going through the source code of some Haskell projects such as Frag (a 3D shooter) and LambdaHack (a roguelike), I finally started to slowly understand how a bigger project in Haskell could look like. So, to start from the bottom and work my way up, I made a blackjack and a video poker game. They’re text based but helped me figure out how to program some simple things in Haskell. (If you’re interested, you can find the sources + binaries here, MIT licensed.)

After finishing those two little cute things, I wanted to tackle the real prob– project, my soccer game wannabe. So I figured out how to read XML files in Haskell to serialize some data. As can be seen from my card games code above, I didn’t quite understand all of the monad concept (and still don’t), which turns out to be a pretty serious drawback when using Haskell to program in a bigger project. As Haskell is a purely functional programming language (one cannot emphasize that enough, I guess), doing something like file I/O without monads is impossible, and without advanced use of monads very tricky once things start to go wrong. The result is that if there is an error somewhere in the XML file to be parsed (my program doesn’t do any validation at the moment) or a bug in a function parsing the XML file, the bughunt may prove to be a very wiery task. So the next thing to do before I go on programming with Haskell is to learn more about monads. Luckily there are a lot of tutorials to the subject on Haskell.org. After that, the smartest thing for me to do would be a rewrite of my XML serializer.

My XML serializer could handle some data, but as I wrote the few XML files manually to test with I realized there is still a lot to design regarding the structure of my soccer game. And in order to see if my design would work, I needed some test scripts to create some XML files that should be able to work with each other. Since creating XML files by parsing text files and adding more or less random data to them is quite an I/O intensive thing to do and since I just wanted to quickly have some scripts that would do the job for me, I decided to do the job in Python instead.

Now, I wasn’t very experienced in Python (to be precise, I had programmed about 20 minutes in Python before this), but I still had somehow had the idea that programming in Python would be extremely fast and easy, especially for such not-very-large programs. After a few days of fooling around with Python and working with the excellent Python lxml library my scripts were finished and it seems I have proved myself correct. Even though my creations look quite terrible (if a Python fan saw my code he’d probably get his eyes hurt) and are written in a procedural fashion reminding me of my BASIC times (maybe Djikstra had a point after all) they do get the job done in the end and I think I can even understand the code.

There are some things I don’t like about Python (mainly the dynamic typing and the fact that is interpreted) and it surely doesn’t fit well for CPU intensive code, but for my XML creation scripts it’s perfect. Python also seems to be very easy to learn (just like Guido wanted it), and my scripts are a living (working) proof for that. I still keep learning Haskell (of course) since it seems even more elegant, faster and is purely functional, but the small Python excursion showed me I should keep clinging to the “right tool for the job” paradigm.

So, what now? Well, there’s the topic of monads to look at. After that I should do a rewrite of my XML serializer. (As boring as it may sound.) Then, well, I should be able to go on with my soccer game project, but with monads this time… We’ll see how it goes.

2 Comments

  1. Have you come and visited us in #haskell on irc.freenode.net? It’s a very beginner friendly IRC channel, and asking questions there is a great way to learn the language.

    Doing file IO without knowing anything about monads in Haskell is quite possible, it’s just that the Haskell IO library happens to be a monad. This doesn’t mean a whole lot, it just means that certain operations are supported for putting IO actions together. When it becomes important to know about monads is when you’re either designing a monadic library, or writing code which will work in multiple monads. For simple I/O, you’re only using the IO monad, and in that case, it’s not necessary to understand things at that level of abstraction, just like using lists doesn’t require an understanding of monads, even though lists happen to form a monad as well.

    I have a small intro to IO in Haskell which doesn’t cover everything, but should be enough to get you started: http://www.haskell.org/haskellwiki/Introduction_to_IO

    If you haven’t already, come and visit on the IRC channel. There are lots of people there who love to answer questions.

  2. I think most games are designed using a polyglot (multi-language) style anyway. Your ‘core’ engine can be written in Haskell (taking advantage of a language well suited to AI and the like).

    You could use (or write) Haskell binding to OpenGL/DirectX or whatever, and hand off to a GPU-targeted language (using HLSL/CG or maybe something chipset specific like Cuda) for very specific processing (shading, etc).

    Your level design and the like might then be scripted in a dynamic language like python or ruby. There a many choices here – (a) expose a simple API using Haskell’s Foreign Function Interface (which is one of the simplest interop mechanisms I’ve ever come across) and call both ways, (b) script your level/character designs using python/ruby/lua/etc and have the internal API generate either configuration or runnable code for the game engine to consume, (c) use parsec to define a simple DSL for “scripting” your game engine.

    Personally I’d go with a combination of (b) and (c), but that’s just my take on it. I like your point about choosing the right tool for the job, so I wonder how far you can take that principle in your design?

    Good luck – sounds like fun! šŸ™‚


Leave a comment