Skip navigation

Tag Archives: functional programming

Those of you who’ve been checking out my projects might have noticed that I wrote my latest one in C++. The two previous projects I had written in Haskell. So why the switch? I’ll write down a small summary of the pros and cons of the both languages that influenced my decision.

I’ll start with the things that spoke for Haskell.

  • Haskell, in general, allows a lot more abstract, safer, higher level way of programming. Of course, you already knew this, but it’s still worth mentioning.
  • Hackage has tons of useful packages which makes using libraries and all the associated bureaucracy really simple. (Hackage is basically a repository consisting of almost all open sourced Haskell programs and libraries.) Combine this with cabal, which downloads, compiles and installs the dependencies for you automatically.
  • C++ compile times, especially with Boost, are abysmal.

And now for the cons, or, put in a more positive light, pros for C++.

  • It’s much easier to reason about performance in C++ than in Haskell. This is given, I guess, and the simple solution is to become a Haskell champion who can spot a space leak a mile away, but it bothers me nevertheless. There was a nice post and thread at Haskell cafe a while back about this.
  • Writing portable code in Haskell is not as easy as with C++. With portable I mean 1) code that runs on x86 across operating systems (Windows, Linux and Mac), and 2) code that runs across architectures (x86, ARM, MIPS, etc.). While portability is not as trendy anymore as it once was, I still have the twisted opinion that high quality code in a higher level language absolutely must be portable, otherwise it’s not high quality, and the Haskell ecosystem currently has limited support for writing portable code. Portable across operating systems is relatively simple with Haskell using GHC (although there are exceptions), but portable across architectures is a pain. GHC, the defacto standard Haskell compiler, actively supports only x86 and doesn’t cross compile. Some of the other Haskell compilers do compile across architectures, but they don’t support all the GHC extensions (which are used by a lot of Hackage packages) and often have a huge performance gap with GHC, which leaves me with zero Haskell compilers I’m 100% happy with. Don’t get me wrong, I still appreciate GHC and think it’s magical, but there’s room for improvement.
  • The Haskell libraries are in a constant flux. I’ve been writing Haskell code for a couple of years now, and each time a new GHC version came out, the old code broke. Usually the libraries included with GHC are updated and the interface was changed. Or GHC behaves a bit differently regarding some minor points and the code breaks. Or cabal, which has its main releases together with GHC, has some new features and the code breaks. There are plans for fixing the libraries once and for all (I can’t find the link now), which I think is a great idea, but when they do (and until they do), there’ll be breakage again.
  • Cabal, while great in general, has its problems, namely what cdsmith felicitously dubbed Haskell’s own DLL hell.

As can be seen from the list, the negative issues I see concerning Haskell are mostly not about the language itself but the infrastructure. That makes sense, I guess; Haskell, although it has a great community, is a less used language, especially in the industry, which makes it more difficult to establish an infrastructure that can compete with the one of, say, C++. The problems I have with C++, on the other hand, concern the language itself, which, although useful, is not really what one might consider the crown jewel of language design.

The infrastructure is at least something that can be fixed.

Advertisements

Here’s the announcement of my latest programming project. It’s called Star Rover 2, and it’s a space flying game. You can fly around in space, trade goods, fight against other ships and complete missions for different governments. It features different difficulty levels, a high score list and several ways for the player to play the game. It’s also the first game I wrote in Haskell that’s actually playable.

Flying between planets

The game itself is quite simple: you start on a planet, and you can buy some cargo if you want before launching into the space. In space, you can fly to other planets and see if you can sell your cargo for a better price. There are other ships in space as well, and you’ll get interrupted every once in a while when coming across one, with the possibility of attacking the other ship. If you win, you get their cargo, and the various governments may have their opinions about the attack as well.

(it looks better in motion :)

Combat in Star Rover 2

As the game progresses, you may earn a reputation among the governing bodies, which leads to new dangers and possibilities. The international relationships are complicated, and attacking a ship of one nationality may not only affect the nationality being attacked but their friends and enemies as well. By playing your cards right you can receive missions from governors, and by completing them you may boost your ranking further.

Captured cargo

The game is quite non-linear; it ends when your ship is destroyed often enough and you are too weak to continue, or when you choose to retire. At the end, your achievements are rated and you may make it to the high score list. Until then, you may choose your activities freely.

You can find Star Rover 2 at Hackage, so if you have cabal, you can install it by running cabal update && cabal install starrover2. You can also fetch the sources from github. As for dependencies, you’ll need SDL, OpenGL and FTGL.

In the beginning, Star Rover 2 was more or less a test of whether I can actually concentrate on one project enough to have a playable game in the end, and I’m glad it’s now reached a state where it can be released. Other than that, I was curious to see what programming such a game actually is like in Haskell, and I’m quite pleased with the results. I started working on Star Rover 2 on my spare time pretty much exactly a month ago, and now it amounts to about 2000 lines of Haskell code. I was a bit worried I couldn’t write a larger project in Haskell, but now I can see how well Haskell scales up to complex tasks. This was also my first project where monad transformers actually came in very handy.

Any feedback and bug reports are of course very welcome.

In this blog post, I list some gem-like web pages that are worth reading if you want to become a better software developer. They’re not simply some sites where you can read about the hype of the week, instead they include insightful material that actually makes you see software development from a whole different perspective.

The need for mentioning the following sites arises from the fact that most web sites and blogs I find in the net usually make me think the writer either tells me some basics about programming I learned years ago or tries to convince me to use some new, brilliant technology which usually involves XML and/or Java. I often get the feeling I’m not part of the target audience and look for things that do a better job on motivating me. As it is quite difficult to find such sites, I’ll spend the few minutes to list some of the sites I’ve found interesting.

Some time ago I stumbled upon a web site called Joel on Software. It’s basically a blog by an experienced software developer, with interesting stories about our industry for us all to read about. It was actually the first software related web page I had found in a long time that managed to inspire me. My favorite article is “Can your programming language do this?“. As another example, if you’ve ever wondered about the Hungarian notation – or cursed at the coding guidelines that force you to use it, even if you can’t see the usefulness behind it, go read what Joel has to say about its history and things may become more clear, although not necessarily less frustrating.

I was glad to find such a page and was hoping to find more. Later I stumbled upon the page of Paul Graham. He shares some similarities with Joel – they both have founded a start-up company and written a lot of nice texts about software development. As a programming language enthusiast, I especially find the essays by Paul Graham involving Lisp interesting.

Some days ago I was looking for a new book on software development to buy and came across Clean Code by Robert Martin. I haven’t bought the book – yet – but searched for some related material and stumbled upon a presentation by Robert Martin titled “What Killed Smalltalk Could Kill Ruby, Too” as well as a blog post drawing parallels between the aforementioned languages and functional languages, namely Lisp and Haskell. The presentation seems very insightful and makes me not only want to learn more about the history of programming languages but also get a copy of the book.

Gaining interest on the new, modern software development techniques I read about TDD and BDD. And when you read about acronyms as these you can’t help coming across the webpage of Martin Fowler sooner or later. Here I also found an interesting text about DSLs, which I feel is an increasingly important – and interesting – topic.

Sites like these help me learn about the new developments in our industry and also make me a better, more efficient developer while still preserving the fun factor. Keep it up!

Following the 0.0.1 release of Freekick and an update to 0.0.2, I started noticing some problems in the implementation that showed a need for code refactoring. There were certain issues that implied I should find out about the internal workings of Haskell, as in, trying to figure out how the language and the implementation I use (Glasgow Haskell Compiler) works in general, especially with regards to threading, scheduling and performance.

The first issue I ran into was about my physics engine. I had defined a maximum velocity for my players of 8 m/s, but after some measurements I found out they were instead quite a bit slower. (A tip for the future: implement a debug panel for having such information when you need it. Measuring something like that shouldn’t be necessary.) This implies that the physics engine has serious flaws. I improved the engine slightly and it works slightly better now (but still not as well as it should), but the improvements lead not only to faster players, but also to strange twitching, a flicker-kind of effect on my SDL client.

To figure out what causes the flicker, I needed to check the code for networking. The way my networking code works at the moment is that the server (physics engine) only sends the positions of the players to the clients but no velocity or acceleration, and my SDL client doesn’t calculate the velocity of the player but only places the player where the server tells the client to. This is the simple method used in Quake that lead to problems back in 1996 when 56k baud modems were fast: with a lag of 200 milliseconds and occasional packet loss the client would spend most of the time not knowing where the moving objects (a.k.a. targets) were exactly located. The remedy that id came up with (a technique that was also used in Duke Nukem 3D) was brought to life in QuakeWorld, where the client would “assume” where the players would be located in based on their current/last known position and velocity. This made Quake playable (and a huge online success) even with slower connections (at the time I had a mere 14.4k modem). The technique is called client side prediction and there’s a small section written about it in Wikipedia.

Now, since I don’t expect a crowd of modem using people starting to play Freekick over the Internet, I didn’t implement client side prediction. Since I have the Freekick server and client running on the same computer lag shouldn’t be the cause for twitching anyways. But to make sure the client was receiving updates about the match state fast enough, I raised the server refresh rate, that is, the frequency with which the physics engine sends the match data to the client(s). The delay between refreshes was 40 milliseconds (using threadDelay), which should actually be enough, but I dropped it to 20 milliseconds for testing. Now, with the lightweight threads that Haskell offers (using forkIO) the refresh rate went up indeed, but the flicker stayed. I tried compiling with the “-threaded” parameter, which made the situation only worse, as the minimum thread delay time using “threadDelay” went up to 40 milliseconds on my computer. In the end I stayed with the lightweight threads, which doesn’t really affect my single core anyways, but this points out a problem when optimising the engine for multiple cores.

However, the problem persisted. Since my CPU was still nowhere near 100%, I figured the problem has something to do with how Haskell handles high precision timing. I’ve tried Frag (a 3D shooter written in Haskell) on my computer, and while I was overall impressed by the game, it was hard not to notice how Frag was twitching with regular intervals as well. As I don’t know if there exists a remedy for the problem, nor if the cause indeed is something Haskell specific or just some obscure bug in SDL or in my client, I wanted to go for a completely different approach.

That’s where C++ comes into play. I’ve actually had quite negative opinions about object oriented programming as well as C/C++ in the past, but on the other hand there are some rather impressive and useful libraries available where bindings to Haskell don’t exist and can only be implemented with a lot of work. The library that I thought of first was OGRE, the massively powerful 3D graphics library written in C++. There are actually a couple of articles about calling C++ functions from Haskell (see here and here), but binding a library like OGRE to Haskell using the described methods is not really something I’d like to spend my free time with.

I know that using OGRE for the client side would

a) make the client run faster and with no flicker, and

b) maybe even look a bit nicer

than the current client implementation using SDL, Haskell and 2D pixel-by-pixel drawing methods. The middle way would be to use the apparently very well written Haskell bindings to OpenGL, but I didn’t really enjoy OpenGL very much the last time I used it five years ago and after seeing OGRE in action and realising using OGRE is actually easier than using OpenGL I don’t really have the motivation. Of course, the biggest reason to use OpenGL would be that I could keep on writing the client in Haskell, but in the end it’s probably easier and more effective using C++ and OGRE.

That being decided, the next thing to do was to freshen up my C++ knowledge. I actually never had much of formal education to C++, instead I was using it much like “C with classes”. Even though that was the primary objective of C++ in the beginning, modern C++ is a completely different subject that I somehow had failed to miss until now. So I went and got me the book The C++ Programming Language by Bjarne Stroustrup and studied it through. I can imagine that a lot of people who have no or very little experience with C or object oriented programming find the book confusing, but for me as someone with good knowledge in C and some idea what C++ is about the book was perfect: it explained all the ways C++ can be used to make programming more efficient and less error prone.

I think it’s time for a small analysis about programming languages. After using C and assembly language I’ve gotten a pretty good picture about what the lower-level job of compilers is: shuffling around with the registers, allocating and keeping track of memory, testing for bits and so forth. Languages like C build on top of this, making the whole resource and control flow management easier to write and read.

On the other hand, Haskell approaches the problem from the other side. Haskell is designed from a mathematical point of view while trying to improve the efficiency of the programmer without clinging to the requirements and constraints of the machine, making Haskell code elegant and robust. To me, writing code in Haskell is almost like using a perfect programming language. Between C and Haskell, there’s C++. My impression about C++ was originally (unsurprisingly) that it is not far away from C, but after seeing how C++ improves on C and adds language features that allow the use of completely new programming paradigms (to C), C++ seems more and more Haskell-like to me.

With Haskell I learned to love the fundamental functional programming features that first seemed a little strange to me (like currying, higher order functions, lambdas etc.). I thought with C++ I’d be giving them away in exchange for pointer arithmetic, buffer overflows and unsafe typing, but fortunately I couldn’t have been more wrong. Nearly all of the C features that don’t seem to fit to modern software development are completely unnecessary in C++, and a lot of functional concepts and other features I’d miss from Haskell are brought in either as built-in C++ features (e.g. safer typing, better mutability control), the standard library (lists, currying, higher order functions) and Boost libraries (smart pointers for memory management, lambdas, serialization).

If you check out the Programming Language Shootout, you’ll see that C++ is (as expected) usually faster than Haskell (but the difference is not tremendous). As is also very well known, there exist about ten thousand times more libraries for C++ than for Haskell. In my opinion, those are pretty much all the aspects where C++ is “better” than Haskell. On the other hand, Haskell code is easier to reason about, significantly shorter and therefore easier to read (in my opinion, at the very least) and the concept of type classes is something C++ and the templates still have a lot to learn from, making generic programming far easier and simpler in Haskell than in C++. However, when writing a client for Freekick, performance as well as external libraries do play an important role in the end, and therefore I’ll go for C++. I’m glad I’ve seen Haskell as the finest example on how elegant code can be written, and I’m also glad it’s easy to use the same concepts in C++.

The next thing I’m going to do is read some more about object oriented design (I’ve got Design Patterns waiting for me) and then go and implement a simple Freekick client using OGRE. For that I need to reimplement the Freekick library in C++ as well, which is a nice exercise for OO design (you should plan to throw the first one away anyway, right?). Having the library in C++ would in theory also make it possible to rewrite the server part in C++, in which case I could use a top notch physics library like Bullet as well. But first we’ll see how the client turns out…