Monday, 17 May 2010

I Know Global Variables are a Bad Idea...

...so why on earth did I use them in Sponge?! Well, there is a reason for that. Inexperience. Sponge is my first attempt at writing an application primarily in Clojure, and as such was a massive learning experience.

One of the design decisions I had to make early on was how to maintain state. I don't ever really need to consider this when programming in Java - I would have instance variables in an object somewhere. But with Clojure there are no objects. So where to put the state?

The decision that I made (and that I have been regretting all day today) was to create global references in the relevant namespaces. This had the advantage that I could easily access the current state from wherever I wanted in the code, and so it was one less level of organisation that I had to deal with. What could possibly go wrong?

Well, a colleague of mine requested the ability to run multiple sessions at once i.e. from the same Sponge GUI, launch different servers listening on different ports. That wasn't possible with a single global state. So, I have spent the whole of today going through the code adding a level of indirection. Instead of a single global state across multiple global variables, I am creating a single 'session' map which holds all the state. This is a hugely painful process that has taught me a valuable lesson:

Global variables in Clojure are as bad as global variables in any other language. Don't use them.

No comments:

Post a Comment