Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

What are the conditions for safe unsafePerformIO? #13

Open
bert2 opened this issue Dec 27, 2022 · 1 comment
Open

What are the conditions for safe unsafePerformIO? #13

bert2 opened this issue Dec 27, 2022 · 1 comment

Comments

@bert2
Copy link

bert2 commented Dec 27, 2022

Observable sharing in general is unsafe, so we use the IO monad to bound this effect, but can be used safely even with unsafePerformIO if some simple conditions are met.

I can't find any explanations on these conditions. Even bought the paper on ACM in the hopes to find them there :(

@noughtmare
Copy link

noughtmare commented Apr 21, 2023

I don't think the conditions are as simple as the authors claim. But I think the main requirement is that the end result should be independent from the particular sharing structure. For example, the list:

x = 1 : x

Is the same as this list which is unrolled one level:

y = 1 : 1 : y

But reifyGraph would produce two different graphs.

Still, we can write a function over the graphs that always produces the same answer regardless of this unrolling. For example a function that checks if all elements of the graph are equal to 1:

f :: Graph (DeRef [Int]) -> Bool
f (Graph g _) = all (\(_, x) -> case x of NilF -> True; ConsF x _ -> x == 1) g

With this function we can safely use unsafePerformIO:

g :: [Int] -> Bool
g = unsafePerformIO . fmap f . reifyGraph

Edit: Actually, g still seems to be unsafe because it can observe compiler optimizations for this expression:

z = let go () = 1 : go () in go ()

If compiler optimizations are disabled g z will loop infinitely but with optimizations it returns True.

So, I think using unsafePerformIO with reifyGraph is almost always unsafe.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants