[Haskell-cafe] Top-level state debate on the wiki

Keean Schupke k.schupke at imperial.ac.uk
Thu Dec 2 05:53:57 EST 2004

Hi John,

    I am not objecting to the top-level TWIs anymore - since I realised 
contexts can be
provided by wrapping the MVar or IORef modules. I just thought the wiki 
the calims of your examples (or maybe the claims are a little 

As far as I can tell adding top level TWIs will change nothing as they 
provide no
guarantees of uniqueness. As nothing changes (exept you don't have to 
pass them
around) - I have nothing to object to in this proposal ... although 
option 2b from the
wiki would be my favourate.

John Meacham wrote:

>Yes. There are lots of ways to do things without global variables, that
>was never in doubt. However randomIO is a part of the haskell standard.
>Why is it not (efficiently) implementable in haskell? There is no
>particular reason it should not be. it should optimize to exactly about
>5 instructions to run the linear congruence algorithm on a static
>location in memory. 
The comment was really about the 'introductory' line in the wiki, which 
to me to be stating there are efficiecy reasons for using global 
variables (false, as
the examples I gave show) and that they provide some static guarantees 
(false, as
I can replace the MVar library and break the unique property - so it is 
not a static
guarantee - It just makes it a little more convoluted to get around)... 
As for randomIO
not being implementable in Haskell, this is true, but it is no more 
efficient than passing
a random sequence generator:

    getRandomSource = do
       a <- newIORef 0
       return (nextRandom a)

       nextRandom n = do -- where g and f are the generator functions
          x <- readIORef n
          writeIORef n (g x)
          return (f x)

> Yes, this would be as fast as the global version*, but it implements
>something else. The entire point of Data.Unique is that one can consider
>the unique supply as part of the world, just like you consider the
>filesystem, the screen, the network, various OS routines, etc as part of
>the world.
Yes, but not necessarily unique. I may have more than one keyboard... Infact
any assumption that a resource is unique is normally a bad one - for example
windows only supporting one display - they probably had to rewrite a lot 
of code
using globals when they wanted to support multi-headed machines.

>  This should be implementable efficiently, after all, you can
>store the counter in a file in /tmp, or just create a stub C file to do
>it, so it is obviously not a bad thing to allow, it is already allowed,
>it just needs to be able to done efficiently or people will resort to
>unsafe hacks like unsafePerformIO which is a serious impediment to
>aggressive compiler optimizations and a plauge on the mathematical
>semantics of the intermediate language.
I agree here - I can always change the filesystem with a OS call
(like chroot) and I can swap the  top-level TWI context with a
wrapper module around  the MVar/IORef module.

> No, because then it would not typecheck. the whole point of Atom.hs is
>that the only way to generate values of type 'Atom' is to go through the
>single unique hash table.  Hence the static guarentee that there is
>always an isomorphism between everything of type 'Atom' and everything
>of type 'String' in the system. This is only made possible by the
>modules ability to hide access to routines which could be used to break
>the invarient (such as the raw global hash). This is obviously a very
>important invarient!
But this can be broken with a wrapper module around IORef that
lets me change contexts... so it is the same in reality, just it
requires a little more thought to get round the "guarantee".

>Let us please not confuse the many philosophical issues against global
>variables in design which I wholeheartily agree with, with what the
>global variables proposal is meant to achieve. It is for use at the very
>lowest level of the libraries. i.e. not to be used by the average
>person. They are for Atom tables, memoization, anti-memoization, I have
>desires to move some of the runtime stable/weak pointer infrastructure
>out of being magic implemented by the runtime, to being implemented in
>haskell itself, this requires the global hash of stablepointers to be
>implementable directly. Ghc itself is getting rid of global variables AS
>SEEN BY THE PROGRAMMER but many libraries still NEED them inside to do their
>clever memoization tricks and fast strings which are required to make
>ghc usable at all. Really, you should not be opposed to them unless you
>are also opposed to the FFI. At some level, deep inside the libraries,
>this functionality is needed, just like the FFI. it is even needed to
>implement the type indexed execution context proposals.
No as I said, my objection was to the summery line which claimed globals
necessary for speed or static guarantees - both claims are false (and I
don't think you claimed as such in the examples - so it is only in regards
to the wiki entry)

>Exposing the fact there is global state will still be a bad idea, their
>usage will be hidden by pure interfaces by good programers,
Of course you cannot stop bad programmers having access to the
same 'tools' once they are in the language.


More information about the Haskell-Cafe mailing list