
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