[Haskell-cafe] global variables

Jules Bean jules at jellybean.co.uk
Thu May 17 18:00:18 EDT 2007


Adrian Hey wrote:
> We've been talking about
> this problem for years, but nothing is ever done about it (a solution to
> this problem isn't even on the agenda for Haskell' AFIAK).

The problem needs talking about, it's important.

My objection was the implication that top-level mutable state was the 
right answer to the OP's question, which my strong hunch is it isn't. I 
don't deny the existence of a problem here.

> No. Even if we stripped away all other code apart from the Haskell rts
> itself (OS, device drivers etc) and performed your IO entirely in
> Haskell (just using peek and poke on bare hardware), you'd still need
> top level mutable state to implement common IO API's (e.g. The socket
> API, does anybody really believe this is entirely stateless?).

I'm not sure that's quite to the point. Clearly we can set up state at 
the top of our main action:

main = do
   sockstate <- initSocks
   graphstate <- initGraphics
   ...
   disposeGraphics graphstate
   disposeSocks sockstate
   exit


Voila. Mutable state which persists for our entire program.

Arguably it's a pain passing around the state explicitly. Alternatively, 
you can argue that passing this stuff around explicitly makes code much 
easier to reason about. And we know a dozen tricks to hide this stuff 
(reader monads, state monads, withSocketsDo-style bracket constructs).

So I don't think this is really the issue, is it?

As I understood it, the issue was more about whether or not *library* 
modules should be allowed to some 'set up' initialisation code to run at 
the beginning of 'main' to start up their own global state. I was never 
convinced this was a nice idea (I don't like the thought than an 
'import' alone can add hidden IO actions to main). Mind you, I'm not 
convinced it's wrong, either. I think it's a hard one.

> I wouldn't dispute the assertion that at the level of complete programs
> or processes, implementations that don't use "global variables" are
> possible. But this does not hold at the level of individual IO library
> API's. If we want to keep our software *modular* (I take we do), then
> we need top level mutable state.

That's assuming you feel having an explicit 'init' command and a 
'withLibXYZDo' construct breaks modularity. It doesn't feel like a 
terrible modularity break to me. (Plenty of C libraries I've used 
require explicit init calls).

> Is it the use of "global variables"?
> Or is it the use of the unsafePerformIO hack to create them?


The latter is definitely a problem.

The former, I'm not sure. My gut feeling is that it is, too.

Jules


More information about the Haskell-Cafe mailing list