
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? Thanks in advance. Cheers, Jorge.

On 26/09/2007, Jorge Marques Pelizzoni
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?
Rule of thumb: If your name isn't Simon*, you shouldn't use unsafePerformIO. * http://research.microsoft.com/~simonpj/ https://research.microsoft.com/~simonmar/ -- Sebastian Sylvan +44(0)7857-300802 UIN: 44640862

2007/9/26, Adrian Hey
Sebastian Sylvan wrote:
Rule of thumb: If your name isn't Simon*, you shouldn't use unsafePerformIO. If this is so, maybe it's time someone (who may or may not be called Simon) gave us a realistic alternative.
There can't be alternatives, unsafeIO throw by the window most guarantee that Haskell can give you and you have to provide them yourself (with a proof of this part of your program), but it's inherent to the nature of the beast, it's what it do ! And you don't need to be called Simon to use it, but you surely need to be careful with it's use if you want to write safe code (you won't need it in most case, only in very specific situations and in writing some new strange libraries). -- Jedaï

Chaddaï Fouché wrote:
There can't be alternatives, unsafeIO throw by the window most guarantee that Haskell can give you and you have to provide them yourself (with a proof of this part of your program), but it's inherent to the nature of the beast, it's what it do !
What about .. http://www.haskell.org/haskellwiki/Top_level_mutable_state This as unsafe a use of unsafePerformIO as you'll ever find, but necessary for real IO libs. Regards -- Adrian Hey

2007/9/26, Adrian Hey
Chaddaï Fouché wrote:
There can't be alternatives, unsafeIO throw by the window most guarantee that Haskell can give you and you have to provide them yourself (with a proof of this part of your program), but it's inherent to the nature of the beast, it's what it do !
What about ..
http://www.haskell.org/haskellwiki/Top_level_mutable_state
This as unsafe a use of unsafePerformIO as you'll ever find, but necessary for real IO libs.
I'm not arguing that there aren't specific current usage of unsafePerformIO that could be better formalized (there are), I'm saying that you can't design an alternative to unsafePerformIO which cover all its applications but stay safer. What we can do with unsafePerformIO is inherently unsafe, even though you can obtain safe results with it (and in some of those use-case, a restricted version of unsafePerformIO could be used and would be safer). -- Jedaï

Chaddaï Fouché wrote:
2007/9/26, Adrian Hey
: Chaddaï Fouché wrote:
There can't be alternatives, unsafeIO throw by the window most guarantee that Haskell can give you and you have to provide them yourself (with a proof of this part of your program), but it's inherent to the nature of the beast, it's what it do ! What about ..
http://www.haskell.org/haskellwiki/Top_level_mutable_state
This as unsafe a use of unsafePerformIO as you'll ever find, but necessary for real IO libs.
I'm not arguing that there aren't specific current usage of unsafePerformIO that could be better formalized (there are), I'm saying that you can't design an alternative to unsafePerformIO which cover all its applications but stay safer. What we can do with unsafePerformIO is inherently unsafe, even though you can obtain safe results with it (and in some of those use-case, a restricted version of unsafePerformIO could be used and would be safer).
In your original post you appear to be making the usual argument about proof obligations and the possibility that unsafePerformIO can be used safely, despite the name (and should only be used this way). I was simply pointing out that there is at least one common use of unsafePerformIO for which this isn't possible (and there is currently no safe alternative). Regards -- Adrian Hey

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

Hello Jorge, Wednesday, September 26, 2007, 6:43:15 PM, you wrote:
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 redirect you to http://haskell.org/haskellwiki/IO_inside and "Tackling the awkward squad: monadic input/output, concurrency, exceptions, and foreign-language calls in Haskell" [http://research.microsoft.com/Users/simonpj/papers/marktoberdorf/marktoberdo...] probably in the last paper i have seen two rules of using unsafePerformIO, but i can't recall them -- Best regards, Bulat mailto:Bulat.Ziganshin@gmail.com

Thanks! That's very clarifying. Bulat Ziganshin escreveu:
Hello Jorge,
Wednesday, September 26, 2007, 6:43:15 PM, you wrote:
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 redirect you to http://haskell.org/haskellwiki/IO_inside and "Tackling the awkward squad: monadic input/output, concurrency, exceptions, and foreign-language calls in Haskell" [http://research.microsoft.com/Users/simonpj/papers/marktoberdorf/marktoberdo...]
probably in the last paper i have seen two rules of using unsafePerformIO, but i can't recall them
-- Best regards, Bulat mailto:Bulat.Ziganshin@gmail.com
Jorge M. Pelizzoni ICMC - Universidade de São Paulo

Things can go arbitrarily wrong if you misuse unsafePerformIO, you can even
subvert the type system.
On 9/26/07, Jorge Marques Pelizzoni
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?
Thanks in advance. Cheers,
Jorge.
_______________________________________________ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe

On 9/26/07, Lennart Augustsson
Things can go arbitrarily wrong if you misuse unsafePerformIO, you can even subvert the type system.
So...if I was in a subversive kind of mood (speaking hypothetically), what would I have to do? -- Dan
On 9/26/07, Jorge Marques Pelizzoni < jpeliz@icmc.usp.br> 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?
Thanks in advance. Cheers,
Jorge.
_______________________________________________ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
_______________________________________________ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe

On Wed, 2007-09-26 at 14:28 -0700, Dan Piponi wrote:
On 9/26/07, Lennart Augustsson
wrote: Things can go arbitrarily wrong if you misuse unsafePerformIO, you can even subvert the type system.
So...if I was in a subversive kind of mood (speaking hypothetically), what would I have to do?
unsafeCoerce :: a -> b unsafeCoerce a = unsafePerformIO $ do let ref = unsafePerformIO $ newIORef undefined ref `writeIORef` a readIORef ref jcc

You could do this:
r :: IORef [a]
r = unsafePerformIO $ newIORef []
cast :: a -> b
cast a = unsafePerformIO $ do
writeIORef r [a]
x <- readIORef r
return $ head x
On 9/26/07, Dan Piponi
On 9/26/07, Lennart Augustsson
wrote: Things can go arbitrarily wrong if you misuse unsafePerformIO, you can even subvert the type system.
So...if I was in a subversive kind of mood (speaking hypothetically), what would I have to do? -- Dan
On 9/26/07, Jorge Marques Pelizzoni < jpeliz@icmc.usp.br> 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?
Thanks in advance. Cheers,
Jorge.
_______________________________________________ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
_______________________________________________ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
_______________________________________________ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe

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 does indeed lose referential transparency, or to be more
Jorge Marques Pelizzoni wrote: precise, it fails to guarantee it. If you call a computation with unsafePerformIO twice it may give different answers, depending on the IO value it wraps. Therefore its up to the programmer to make sure that it doesn't matter how many times the computation is executed. The Haskell compiler may (or may not) optimise multiple calls into one call. If the result is not required then a lazy computation may mean that the computation is never used. If you have two calls to unsafePerformIO then you can't rely on the ordering, and the strictness analyser may change the order as part of optimisation. You get the picture. So in summary, its up to you to make sure that the computation wrapped by unsafePerformIO has no side effects. For instance if you wanted to read a configuration file and make the result look like a pure value then that would be a reasonable use for unsafePerformIO: reading the file is almost free of side effects (apart from updating the last-accessed time in some file systems), and the file isn't likely to change while you are reading it. Paul.

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?
Old thread, but I don't think anyone mentioned this text from the GHC FAQ: http://haskell.org/haskellwiki/GHC:FAQ#When_is_it_safe_to_use_unsafe_functio... Cheers, Simon
participants (11)
-
Adrian Hey
-
Bulat Ziganshin
-
Chaddaï Fouché
-
Dan Piponi
-
David Roundy
-
Jonathan Cast
-
Jorge Marques Pelizzoni
-
Lennart Augustsson
-
Paul Johnson
-
Sebastian Sylvan
-
Simon Marlow