# Using unsafePerformIO safely?

**URL:** <https://discourse.haskell.org/t/using-unsafeperformio-safely/4146>\
**Category:** Uncategorized\
**Created:** [February 28, 2022, 2:41pm UTC](https://discourse.haskell.org/t/using-unsafeperformio-safely/4146 "2022-02-28T14:41:23Z")\
**Posts on this page:** 1\
**Showing post:** 68

<div class="post-metadata">

**Author:** ![atravers](https://avatars.discourse-cdn.com/v4/letter/a/45deac/32.png) [@atravers](https://discourse.haskell.org/u/atravers)\
**Post date:** [July 22, 2022, 10:31am UTC](https://discourse.haskell.org/t/using-unsafeperformio-safely/4146/68 "2022-07-22T10:31:11Z")

</div>

[&nbsp;](http://discourse.haskell.org/t/mutability-side-effects/4899/6)

> [@jaror](#):
>
> True, to get modularity, modules have to communicate which assumptions they make about the use of `unsafePerformIO` in [the] rest of the program.

Unfortunately, those assumptions would need to be pessimistic by default because of [transitivity](https://nrich.maths.org/1345): a definition in one module can _indirectly_ depend on a definition in another which uses `unsafePerformIO`. For most codebases, that could end up _“tainting”_ many modules, quite possibly the majority of them.

It would then probably be easier to just assume the worst - that any module can be tainted - and not bother with those communications.

* * *

> [@jaror](#):
>
> Now I’m also wondering, a use of `unsafePerformIO` that is often considered safe is if all the side effects are encapsulated. […]

That resembles the _“safe-usage”_ requirements for `unsafeLocalState`:

> [@](#):
>
> **unsafeLocalState :: IO a → a**
> 
> Sometimes an external entity is a pure function, except that it passes arguments and/or results via  
> pointers. The function `unsafeLocalState` permits the packaging of such entities as pure functions.  
> The only IO operations allowed in the IO action passed to `unsafeLocalState` are
> 
> (a) local allocation (`alloca`, `allocaBytes` and derived operations such as `withArray` and `withCString`), and
> 
> (b) pointer operations (`Foreign.Storable` and `Foreign.Ptr`) on the pointers to local storage, and
> 
> (c) foreign functions whose only observable effect is to read and/or write the locally allocated memory.
> 
> Passing an IO operation that does not obey these rules results in undefined behaviour.
> 
> It is expected that this operation will be replaced in a future revision of Haskell.
> 
> [The Haskell 2010 Report](https://www.haskell.org/definition/haskell2010.pdf) (page 269 of 329).

…perhaps this is as close as anyone will get for now to a guide for the safe use of `unsafePerformIO`.

---

_[View the full topic](https://discourse.haskell.org/t/using-unsafeperformio-safely/4146)._
