Architecture of Evil: Writing C In Haskell

farnsworth good news

It’s been a long road, but today our hard work pays off. You can set globals in Haskell! No more fussing about with State monads, I’m talking big boy non-thread-safe globals. This glorious piece of functionality thanks to the Data.IORef package.

someGlobal = unsafePerformIO $ newIORef "foo"

This is how you set a global. We create a global called someGlobal, and give it the initial value of foo. You’ll notice I wrap that in unsafePerformIO. Like the name implies, it is perfectly ok* to do this, after all: the IO Monad exists only to annoy you, and serves no actual purpose.

* Seriously though, don’t ever do this; if I catch you doing this in real code, then we are no longer friends.

This global can be used like so:

main = do g1 <- readIORef someGlobal putStrLn $ show $ g1 writeIORef someGlobal "bar" g2 <- readIORef someGlobal putStrLn $ show $ g2 return ()

Running this code produces the following output:

"foo" "bar"


On A Serious Note

Now that we’ve all had a good laugh; please don’t ever do this. I discovered this module while messing around with the haskell bindings to OpenGL. If you’ve ever used OpenGL for even a second, you surely noticed that there is crazy amounts of state being tracked. Given this, and the fact that nobody is just going to make a “Haskell replacement for OpenGL”, an IORef seems like a reasonable alternative to some monolithic State monad transformer stack.

However, aside from supporting legacy C libraries, I can see no good reason to ever use IORef instead of State

Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: