[Haskell] Re: Global Variables and IO initializers

Benjamin Franksen benjamin.franksen at bessy.de
Sat Nov 6 22:16:54 EST 2004

As an experiment, I just finished to change the Haskell Web Server with 
Plugins such that all global variables (unsafePerformIO-style) are replaced 
by standard argument passing. It wasn't difficult. The main work was

(1) get it to compile with ghc-6.2.2
(2) understand how the code is organized
(3) find out that implicit parameters have too many limitations to be usefull 
as a general replacement
(4) find appropriate pattern(s) to get rid of the globals

Overall I think the code has somewhat improved. The parts that were written 
with global variables are now shorter and more easily understood.

What I didn't expect was that modularity did *not* suffer, quite the opposite: 
the interfaces became smaller. For instance the MimeTypes module exported two 

initMimeTypes :: String -> IO () 	-- argument is file path to mime.conf
mimeTypeOf    :: String -> MimeType	-- convert file path to mime type

where unsafePerformIO was used not only to create the global variable for the 
mime type map, but also for the conversion function (because it had to access 
teh global var).

The new interface has only one routine:

initMimeTypes :: String -> IO (String -> MimeType)
-- argument is file path to mime.conf
-- result is file path to mimetype converter

and no unsafe feature is used: the result is a pure function.

Of course, the downside is that some of the functions (not many) now have one 
or two additional arguments. OTOH one could argue that this is in fact an 
advantage, as it makes all the dependencies crystal clear. It turned out, for 
example, that of the two logging modules, ErrorLogger and AccessLogger, the 
latter had a hidden dependency on the former. That dependency is now 
expressed explicitly by giving the initialization routine for the 
AccessLogger an extra argument (namely the error logging function).

Surely this is just one example, and not a very complex one. Nevertheless, I 
am now less convinced that using global variables is in fact a good idea, 
however convenient it may seem at first.


More information about the Haskell mailing list