[Haskell] Real life examples

John Meacham john at repetae.net
Thu Nov 25 05:19:02 EST 2004

On Thu, Nov 25, 2004 at 09:54:41AM +0100, George Russell wrote:
> John Meacham wrote (snipped):
> > George Russell's library is precicly an invalid use of unsafePerformIO.
> > Internally, it does the invalid unsafePerformIO (newIORef) trick which
> > is exactly the problem we are trying to solve. hiding it in a module 
> doesn't
> > make it go away.
> Why does it matter to you if it uses unsafePerformIO, so long as you are
> protected from all the unsafe consequences?
> Would you be happier if I required all values to instance (Read,Show) and
> then implemented exactly the same interface with this additional restriction
> using completely standard Haskell 98 by writing values to files and reading
> them back again?

No because this would be inefficient, the very problem I am trying to
solve is the fact that you must currently choose between being unsafe
(with unsafePerformIO) or very inefficient (with Read/Show and
environment variables or files) or resort to a foreign language. 

> > I am not positive, but it also would also add the overhead of a
> > finitemap lookup across all global variables for every look up. which
> > doesn't really meet efficiency requirements. a global counter should
> > only need a single peek poke to a constant location, not some data
> > structure lookup.
> Oh really, we're not arguing about efficiency at this stage of the game
> are we?  Actually you could implement the whole thing with a single
> hash table.  I would have done, if TypeRep and ThreadId exposed their
> internal integer contents for hashing purposes.

I should say that efficiency is the only thing I have been concerned
about in this conversation. As I said in the mdo proposal, there is no
efficient and safe way to do global variables in haskell.  Your library
addresses a different issue, it provides an interface for global
variables, but it doesn't address the fundamental problem that your
library or ones like it cannot be implemented in haskell. People have
been hiding unsafePerformIO global variables in modules for a long time,
such as Data.Unique in the main libraries. However common use doesn't
make it any safer :) It is not that unsafePerformIO is inherently
unsafe, it is that this particular use. the use for global variables is
unsafe which means that in the nice desugared typed lambda calculus core
of ghc, some terms 'mysteriously' can't be beta reduced. it means that
newtype Foo = Foo Int and Int cannot be treated the same by backend CSE
routines so newtypes must be propegated deep into the backend. it means
your {-# NOINLINE #-} pragmas become manditory for program correctness
rather than just a user preference. It is just not a nice thing to deal
with from a theory and hence practice point of view, hiding things in a
module does not change these problems for the compiler. ghc has been
pretty good such that the unsafePerformIO hack works, but nothing
guarentees it will work in the future. in fact, it would be hard to
prove it works in every case now even with cse disabled since so many
properties of the lambda calculus are broken. 


John Meacham - ⑆repetae.net⑆john⑈ 

More information about the Haskell mailing list