Cleaning up threads in ghcid - Haskell

Welcome to the Functional Programming Zulip Chat Archive. You can join the chat here.

Julian KG

This is actually a great example of a usage of unsafePerformIO that goes against conventional wisdom, but is really hard to make a practical argument against. I mean what documentation are you loosing by dropping the IO monad considering you can't get a top level pure IORef without using an unsafePerformIO? Who would of thought, mutable global variables in Haskell...

Sandy Maguire

GHC did this for a while, and it ended up biting them

Sandy Maguire

GHC's behaviour is governed to a large extent by command-line flags. These command-line flags are by definition constant over a given run of GHC, so in early versions of GHC we made the values of these flags available as top-level constants. For example, there was a top-level value opt_GlasgowExts of type Bool, that governed whether certain language extensions should be enabled or not. Top-level constants are highly convenient, because their values don't have to be explicitly passed as arguments to all the code that needs access to them.
Of course these options are not really constants, because they change from run to run, and the definition of opt_GlasgowExts involves calling unsafePerformIO because it hides a side effect. Nevertheless, this trick is normally considered "safe enough" because the value is constant within any given run; it doesn't invalidate compiler optimisations, for example.
However, GHC was later extended from a single-module compiler to a multi-module compiler. At this point the trick of using top-level constants for flags broke, because the flags may have different values when compiling different modules. So we had to refactor large amounts of code to pass around the flags explicitly.
Perhaps you might argue that treating the flags as state in the first place, as would be natural in an imperative language, would have sidestepped the problem. To some extent this is true, although purely functional code has a number of other benefits, not least of which is that representing the flags by an immutable data structure means that the resulting code is already thread-safe and will run in parallel without modification.