
On Thu, 2009-02-05 at 16:11 -0500, Andrew Wagner wrote:
So we all know the age-old rule of thumb, that unsafeXXX is simply evil and anybody that uses it should be shot (except when it's ok).
I understand that unsafeXXX allows impurity, which defiles our ability to reason logically about haskell programs like we would like to.
Not just that! Parametric polymorphism is unsound in combination with mutable values; but unsafePerformIO turns on exactly that combination. unsafeCoerce :: alpha -> beta unsafeCoerce x = unsafePerformIO $ do let r = unsafePerformIO $ newIORef undefined r `writeIORef` x readIORef r
My question is, to what extent is this true?
unsafePerformIO is a true function --- in the absence of any fancy compiler trickery --- on a small subset of its domain. Outside of that subset, I would regard use of unsafePerformIO simply as a bug --- violation of an unchecked precondition. Period.
Suppose we had a module, UnsafeRandoms, which had a function that would allow you to generate a different random number every time you call it.
unsafePerformIO does not allow you to guarantee this! If I defined myRandomNumber = unsafePerformIO $ randomNumber then the compiler is permitted to call randomNumber (at most) *once*, and use that number throughout the program.
The semantics are relatively well-defined,
Leaving aside the issue above, I would think complete randomness was nearly the worst possible case, semantically. (The *worst* worst possible case would be non-statistical non-determinism --- which is what you actually get here).
impurity is safely sectioned off in its own impure module, which is clearly labeled as such. How much damage does this do?
Well, it forces me to chase your libraries import lists to decide whether I want to trust your code, for one thing. Haskell is all about making it easier to audit code, not harder.
Can we push the lines elsewhere?
I'd rather not.
Is sectioning unsafeXXX into Unsafe modules a useful idiom that we can use for other things as well?
I'd rather not write other unsafe functions at all. Sectioning off things that need to be unsafe into pure solutions --- like, say, monads --- is a much better idea. (Go read the global variables thread from last year). jcc