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
misrepresented
the calims of your examples (or maybe the claims are a little
exaggerated)...
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
seemed
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)
where
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.
Keean.