[Haskell-cafe] unsafePerformIO: are we safe?

David Roundy droundy at darcs.net
Wed Sep 26 11:33:44 EDT 2007

On Wed, Sep 26, 2007 at 11:43:15AM -0300, Jorge Marques Pelizzoni wrote:
> Hi, all!
> This is a newbie question: I sort of understand what unsafePerformIO does
> but I don't quite get its consequences. In short: how safe can one be in
> face of it? I mean, conceptually, it allows any Haskell function to have
> side effects just as in any imperative language, doesn't it? Doesn't it
> blow up referential transparency for good? Is there anything intrinsic to
> it that still keeps Haskell "sound" no matter what unsafePerformIO users
> do (unlikely) or else what are the guidelines we should follow when using
> it?

unsafePerformIO *is* unsafe, but it can be safely used.

For instance, Data.Bytestring uses unsafePerformIO to access memory in byte
arrays, but since that memory is hidden within a bytestring, so long as
Data.Bytestring itself is bugfree (which I believe it is), referential
transparency is preserved, and everything is fine.  Actually, this is
*almost* true.  There is a function to mmap a file into a bytestring, and
the result is only referentially transparent if that file doesn't change.
But in any case, one can judge the correctness of the code by examining
only Data.Bytestring and its exported API.  Data.Bytestring also exports (I
believe) some unsafe* functions that are also unsafe, but that's generally
considered okay, with the assumption that it's the responsibility of anyone
using an "unsafe" function to determine what criteria are required in order
to preserve referential transparency, and general safety and sanity.

In short, any use of unsafePerformIO should be encapsulated within a
module, with an exported API that preserves safety (with possible exception
of unsafe*-named functions, which ideally should be documented in regard to
precisely what is required to use them safely).

The general rule with unsafe functions is that if you don't understand
what's required to use them safely, you shouldn't use them.
David Roundy
Department of Physics
Oregon State University

More information about the Haskell-Cafe mailing list