[project @ 1999-09-15 08:00:11 by simonpj]
authorsimonpj <unknown>
Wed, 15 Sep 1999 08:00:11 +0000 (08:00 +0000)
committersimonpj <unknown>
Wed, 15 Sep 1999 08:00:11 +0000 (08:00 +0000)
Extra words about unsafePerformIO

ghc/docs/libraries/IOExts.sgml

index 2af0789..6038706 100644 (file)
@@ -2,11 +2,34 @@
 <label id="sec:IOExts">
 <p>
 
+(Documetation for this library is sadly inadequate.)
+
 This library provides the following extensions to the IO monad:
 <itemize>
 <item>
 The operations <tt/fixIO/, <tt/unsafePerformIO/ and <tt/unsafeInterleaveIO/
-described in <cite id="ImperativeFP">
+described in <cite id="ImperativeFP">.
+<p>
+Everyone knows that if the I/O computation wrapped in <tt/unsafePerformIO/ 
+performs side effects, then the relative order in which those side effects
+take place (relative to the main I/O trunk, or other calls to <tt/unsafePerformIO/)
+is indeterminate.  It is less well known that <tt/unsafePerformIO/ is not type safe.
+For example:
+<tscreen><verb>
+  test :: IORef [a]
+  test = unsafePerformIO $ newIORef []
+
+  main = do
+          writeIORef test [42]
+          bang <- readIORef test
+          print (bang :: [Char])
+</verb></tscreen>
+This program will core dump.  This problem with polymorphic references is
+well known in the ML community, and does not arise with normal monadic use
+of references.  There is no easy way to make it impossible once you use
+<tt/unsafePerformIO/.  Indeed, it is possible to write
+<tt>coerce :: a -> b</tt> with the help of <tt/unsafePerformIO/.
+So be careful!
 
 <item>
 References (aka mutable variables) and mutable arrays (but no form of