[Haskell-cafe] Current situation regarding global IORefs

John Meacham john at repetae.net
Thu Apr 27 15:37:25 EDT 2006

On Thu, Apr 27, 2006 at 11:09:58AM +0100, Adrian Hey wrote:
> What really frustrates me about all this is that AFAIK there are no
> significant technical or theoretical reasons why we can't get
> this safety (without resort to the unsafePerformIO hack). The
> only serious obstacle seems political, with this very strange but
> apparently widespread dogma about so called "global variables"
> being inherently evil, regardless of the circumstances or purpose
> for which they are used.

indeed. perhaps we just need to come up with a more functional name than
'global variables'. like 'universal monad' or 'world transformer', maybe
'augmented IO'. :) 

I am tired of having to apologize for using them, they really are the
right solution to a number of practical problems when writing real-world
code. Every haskell programer depends on them whethre they know it or
not, they are just abstracted away in libraries, but the bottom line is
that someone needs to be able to write those libraries.

my ForeignData proposal (on the wiki) fills a hole in the haskell FFI
that can somewhat mitigate the problem, but only for Storable strict

I have thought a safe 'StorableRef' would be a useful data type, that
uses peeks and pokes internally for very fast mutable state, but
provides a safe interface.

There is also the 'dependingOn' primitive which is in jhc and I think
will be in ghc (?) that lets you do global variables without having to
turn off cse.

dependingOn :: a -> b -> a
dependingOn = ...

where it has the same meaning as const, but introduces an artificial
dependence of its return value on its second argument. so you can do

data Var1 = Var1

{-# NOINLINE myVar #-}
myVar :: IORef Int
myVar = unsafePerformIO $ newIORef (0 `dependingOn` Var1)

and now myVar cannot be cse'd with anything else because Var1 will not
match anything of another type.

still not ideal though.

(I have been finding all sorts of uses for 'dependingOn' when it comes
to various tasks)

> >Let me just add one thing.  Sometimes you hear the argument
> >"I need a global IORef here because it's to track the use of my
> >single screen" (or keyboard, or elevator, or some some
> >other gizmo in th real world).

heh. the canonical strawman tactic. :)

> No, this is not the justification for the creation of top level TWI's.
> This is the justification for not requiring that the API that mutates
> a particular top level TWI state takes that state as an explicit
> argument. There's no point if there is (and can be) only one of them.
> This is why you don't have to pass an OS state handle to every IO
> function that interacts with "the" OS (note singular).

it is not just about convinience, for instance my 'Atom' module in jhc
and ginsu depends on the fact you cannot pass in different states for
correctness. its API is purly funcitonal, but it needs to use global
state internally. Haskell has great tools for abstraction, global state
would be another one. What it boils down to is that it helps you write
more correct code in certain cases and there is no reasonable


John Meacham - ⑆repetae.net⑆john⑈

More information about the Haskell-Cafe mailing list