[Haskell-cafe] Just how unsafe is unsafe
jonathanccast at fastmail.fm
Thu Feb 5 16:33:13 EST 2009
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
> 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
More information about the Haskell-Cafe