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

Adrian Hey ahey at
Tue Nov 23 04:26:57 EST 2004

On Monday 22 Nov 2004 4:03 pm, Benjamin Franksen wrote:
> This is getting ridiculous. At least two workable alternatives have been
> presented:
> - C wrapper (especially if your library is doing FFI anyway)
> - OS named semaphores

Neither of these alternatives is a workable general solution.
There are several significant problems with both, but by far
the most significant problem (at least if you believe that top
level mutable state is evil) is that they both rely on the use
of top level mutable state. If this is evil it is surely just as
evil in C or OS supplied resources as it is in Haskell.

The fact that one solution requires the use of a completely different
programming language and the other requires the use of a library which
could not be implemented in Haskell (not without using unsafePerformIO
anyway) must be telling us that there something that's just plain missing
from Haskell. IMO this is not a very satisfactory situation for a language
that's advertised as "general purpose".

> Further, as for "evidence or credible justification" for the my claim, you
> can gather it from the numerous real-life examples I gave, and which you
> chose to ignore or at least found not worthy of any comment.

I have no idea what examples you're talking about. Did you post any code?
If so, I must have missed it for some reason. Perhaps your're refering
to your elimination of unsafePerformIO from a library you were writing.
It's not really possible to comment on the significance of you being
able to eliminate top level mutable state in this case without knowing
why you were using it in the first place. 

> Of course,
> these examples are only annecdotal but I think this is better than a
> completely artificial requirement (like your "oneShot").

Being able to avoid the use of top level mutable state sometimes (or even
quite often) is not proof that it's unnecessary, especially when nobody
(other than yourself presumably) knows why you were using it in the first
place. However, the existance of just one real world example where it does
appear unavoidable is pretty convincing evidence to the contrary IMO.
It may yet prove to be avoidable, but nobody has managed to show that and
I certainly can't think of a way.

> You have been asked more than once to present a *real-life* example to
> illustrate that
> (a) global variables are necessary (and not just convenient),
> (b) both above mentioned alternatives are indeed unworkable.

I knew this would happen. I was asked to provide an example and I *did*.
I gave the simplest possible example I had of the more general problem,
and now this whole thread has consisted of either repeated denials of
the reality of even this simple problem (something you've just done again)
or protracted discussions over various half baked non-solutions to
this one particular problem (such as those you identify above) without
seeing the real underlying general problem.

(See my response to Keaan) You have the same basic problem when dealing
with any unique stateful resource. Even the state handle passing solution
that I believe yourself, Keaan and Lennart would advocate is unsafe
without using top level mutable state one way or another (a problem that
could be fixed quite easily by using "oneShot" at the top level I might add).

> > You have yet to
> > explain how you propose to deal with stdout etc..
> I see absolutely no reason why stdxxx must or should be top-level mutable
> objects. They can and should be treated in the same way as environment and
> command line arguments, i.e.
> getArgs :: IO [String]
> getEnv :: String -> IO String
> getStdin, getStdout, getStderr :: IO Handle
> Note that (just like environment and command line arguments) these handles
> may refer to completely different things on different program runs.

Sure, Peter Simons suggested the same thing. I have no great objection,
but why do this? I mean what extra safety does this buy you? Anybody can
still get at stdout and write anything they like to it.

The only difference is that instead of writing..

 do ...
    foo stdout

..they now have to write..

 do ...
    stdout <- getStdout
    foo stdout

I don't see why the former should be regarded as a source of great evil
which is somehow eliminated by the latter.

Adrian Hey

More information about the Haskell mailing list