GHC Runtime Loading
Note: Since I wrote this dynamic loader for Haskell a long time ago, quite a few advancements have been made, so I’m no longer supporting this package. See the end of the page for discussion on the state-of-the-art in Haskell dynamic loading.
Introduction to Dynamic Loading & Plugins
Dynamic Loading is an important feature for building extensible programs and larger applications. It allows the program to load in code contained in a file, at runtime, and execute it. It’s a simple concept, but it leads to applications which can be very easily extended, sometimes in ways the original author never imagined.
If you’re still not convinced of the power of dynamic loading, think of WinAmp (a.k.a. XMMS :), which uses plugins to read files and perform device-specific output (not to mention all of its fantastic visualisation plugins). Each file type (MP3, WAV, OGG, XM, etc) is handled by a separate plugin, which means that it’s incredibly easy to extend WinAmp to play different types of media files.
Other notable projects which extensively use plugins are the Linux kernel (think kernel modules), Emacs, the Windows device driver model, the entire DirectX/gstreamer media framework, and the Apache web server. These projects would not be what they are today without their modular, extensible design.
Plugins in Haskell
The good news is: GHC has had, for quite a while now, the capability to load in Haskell modules at runtime. (If you use GHCI, that’s exactly what it does!) The bad news is: you can’t normally get at the functions which will do this for you. The better news is: thanks to some handiwork, you now can get at the functions which perform runtime (un)loading of modules; you’ll need to download a special RuntimeLoader module which allows you to do this.
To use it,
import RuntimeLoader ... -- Load the plugin file plugin <- loadObject "MyPlugin.so" -- Load the function inside the plugin adder <- loadFunction plugin "addFunction" :: IO (Int -> Int -> Int) -- Execute the function let i = adder 2 3
That’s all you need to do to load a plugin. (Okay, not quite, you have to add a few flags to the ghc commandline too ;-).
If you’re interested, I’ve packaged up a small, example program called “TextFilter” which includes the RuntimeLoader module and demonstrates how to use it. Download it and get hacking!
Sorry, there’s no separate package for just the RuntimeLoader by itself: I think the TextFilter example is small enough that packaging it separately from the RuntimeLoader isn’t worth the hassle for you or me.
RuntimeLoader Redux
Since the release of RuntimeLoader in 2002, a few other people have taken up the challenge to make Haskell a more dynamic language. If you’re interested in this, have a look at:
- HWS-WP, a.k.a “Haskell Web Server With Plugins”. Martin Sjöaut;ren took the original Haskell Web Server written by Simon Marlow many moons ago, and extended it to have Apache-style modules.
- Hampus Ram’s DynamicLoader, which provides a higher-level API than my RuntimeLoader module.
- I worked with Don Stewart, Sean Seefried and Manuel Chakravarty on a paper named Plugging Haskell In, which is complemented by an implementation of a far more complete dynamic framework for Haskell named hs-plugins. Thanks to the incredible work of Crazy Don, hs-plugins has become mature enough to write an interactive Haskell shell in less than 100 lines of code, and even lets you call Haskell functions from C far too easily. Check it out, dude.