Top Level TWI's again was Re: [Haskell] Re: Parameterized Show

Adrian Hey ahey at
Tue Nov 23 03:33:30 EST 2004

On Monday 22 Nov 2004 11:26 am, Keean Schupke wrote:
> Adrian Hey wrote:
> >Just repeating this again and again doesn't make it any more true.
> Ditto... I for one think the best solution is to use the language as
> intended and pass the values as function arguments.

I guess you mean the usual handle based approach, but this makes no
sense at all for a Haskell interface to some *unique* stateful resource
(eg. a piece of raw hardware or "badly designed" C library). The handle
is a completely redundant argument to all interface functions (there's no
need identify which thing is being referenced because there is only one).

Furthermore it still leaves you with the problem ensuring that users
don't use whatever "openUniqueThing" routine that creates and initialises
the state multiple times to end up with two or more different TWIs which
are all trying to reflect state changes in the same unique resource.
AFAICS the only way of preventing this requires the use of top level
mutable state, so this solution is a non-solution (the only safe way
of using this "solution" still leaves you with the original problem).
Of course this problem could be solved quite simply with a top level..

 userOpenUniqueThing <- oneShot openUniqueThing

Unfortunately this is not an option because it creates a top level MVar
(and so it must be evil).

The only thing to be said in favour of the handle based approach is
that forcing users to get the state handle does ensure that any
necessary external initialisation has been performed prior to using
the resource. But there are other ways to do this too (like prefixing
every exported interface function with "userInit" instead of exporting
userInit itself).

> As pointed out
> on this list - the only possible situation where you cannot do this is
> when interfacing to a badly written C library.

This is one situation, but certainly not the only possible one. You have
the same problem with interfacing to any unique stateful resource (or
even if you have a multiple but finite supply of these resources). 

> This is true - but only because unsafePerformIO exists. Without it
> World is simply a value passed via the IO Monad.

Huh? Top level TWIs are just part of the initial world state (as seen
by main). We can argue about whether or not they are needed, but their
existence surely doesn't make the situation any worse than it already

> I would ask an alternative question - is it possible to live without
> unsafePerformIO?

Not at present.

> I have never needed to use it!

I have a feeling that those folk who think they don't need it are
those who enjoy the luxury of doing all their IO via pre-supplied
"Haskell user friendly" libraries and haven't given much thought
to how these libraries actually work or how they could be
implemented in Haskell if they didn't already exist (without using
the unsafePerformIO hack of course). 

Adrian Hey

More information about the Haskell mailing list