
Adrian Hey writes:
I don't see any value in problems that are specifically designed so that they can be solved only with a global entity.
Even if it was true that I had "specifically designed" this problem, it's existance is of some interest I think.
Perhaps my choice of words wasn't really good. I am sorry. What I meant to say is that I have never once _needed_ a global variable yet. Never. On the other hand, there were plenty of occasions where I had trouble with global variables in other people's code. I'll readily admit that a safe way to implement them in Haskell is probably an interesting research subject, but I honestly don't expect to be using that feature any time soon. It's a completely abstract concept for me; I associate no practical value with it.
[Creating top level "things with identity" is] what many in this thread assert is bad code, yourself included it seems. Yet this is widely used in many programs and libraries, even in ghc itself I believe. Not to mention stdin etc.. (again).
Right, but it is by no means _necessary_ to have a global 'stdin'. It could equally well be defined as stdin :: IO Handle and it would work just the same. The fact that it isn't implemented this way is for historical reasons, IMHO, not because it's a good idea.
Because code like that is very hard to get right and very hard to maintain, and I don't want to use library code that uses this technique if I can avoid it.
This is dogma I think.
Yes, you are right. Nonetheless, it is a dogma that's not just arbitrary; it is motivated by experience with real-life code. Just ask the C++ folks about the wonders of global variables that are actually complex classes with a constructor and a destructor. You wouldn't believe through what kind of hoops you have to jump if you want to write reliable code that has to deal with this. For instance: Where do you catch exceptions a constructor throws that is executed before your main() routine is? How do you deal with exceptions that are thrown after your main routine has _ended_? The effect is that the language is full of strange and very counter-intuitive mechanisms, just so that they can implement something which -- in _my_ opinion -- is completely useless to begin with!
There are many libraries you will need to try to avoid using if this is really your position.
Let's say ... I try to compromise rarely, but I do have to compromise, unfortunately. In fact, I have to admit that my own Haskell code contains unsafePerformIO at the occasion, too. Not that I'd need it, but I am too damn lazy as well. :-) Peter