unsafePerformIO

Simon Peyton-Jones simonpj@microsoft.com
Tue, 24 Sep 2002 16:00:17 +0100


Koen

Based on this info, how would you like to write the notes you would like
to see on unsafePerformIO?  The starting point is at
http://haskell.cs.yale.edu/ghc/docs/latest/html/base/GHC.IOBase.html#uns
afePerformIO

If you write the notes, we'll check their veracity and add them.  We'll
do the formatting too!

Simon

| -----Original Message-----
| From: Simon Marlow [mailto:simonmar@microsoft.com]
| Sent: 24 September 2002 13:59
| To: Koen Claessen; glasgow-haskell-users@haskell.org
| Subject: RE: unsafePerformIO
|=20
| > But it is a fact that many of us have at least some idea of
| > what happens "under the hood" when we use unsafePerformIO.
| > This is also described in your paper "Stretching the storage
| > manager: weak pointers and stable names in Haskell".
| >
| > However, I for example have no idea what happens when
| > unsafely executing something that throws exceptions,
| > performs a forkIO, something that uses MVar's, etc.
|=20
| Exceptions: an exception raised by the computation inside
| unsafePerformIO will be propagated to the enclosing expression, as per
| the normal semantics for imprecise exceptions.  The exception raised
by
| an application of unsafePerformIO may of course also be imprecise;
| consider 'unsafePerformIO $ (1/0 + error "foo") `seq` return ()'.
|=20
| The behaviour of forkIO and other side-effecting operations inside
| unsafePerforIO can I think be explained by the following statement: if
| an expression "unsafePerformIO e" has been reduced to head normal
form,
| then all the I/O computations in e have been performed.  The exact
| timing of the evaluation is underspecified, just as any other
expression
| in Haskell.  However, if you're using unsafePerformIO with real side
| effects, then I suspect that what you're doing is highly dodgy and you
| should find another way to do it :-)
|=20
| Does that help?
|=20
| As for sharing, we currently don't provide any guarnatees, although we
| should.  It is currently the case that if you write
|=20
| a =3D unsafePerformIO (putStr "hello")
| b =3D unsafePerformIO (putStr "hello")
|=20
| and both a and b are evaluated, then you may get either one or two
| "hello"s on stdout.  You can currently make things more deterministic
by
| (a) adding NOINLINE pragmas for a and b, and (b) using the flag
-fno-cse
| to disable common sub-expression elimination.  Then you'll get exactly
| two instances of "hello" on stdout, although we won't guarantee that
| behaviour for ever.  At some point we'll fix it so that
unsafePerformIO
| applications are never duplicated or coalesced.
|=20
| If you're interested in when unsafePerformIO is "safe" to use, see:
|=20
|
http://www.haskell.org/pipermail/glasgow-haskell-users/2002-July/003683.
| html
|=20
| (and see my followups for an alternative view).
|=20
| Cheers,
| 	Simon
| _______________________________________________
| Glasgow-haskell-users mailing list
| Glasgow-haskell-users@haskell.org
| http://www.haskell.org/mailman/listinfo/glasgow-haskell-users