{
  "$type": "site.standard.document",
  "bskyPostRef": {
    "cid": "bafyreidgibtwb3ezfyptpj6epfgcsufhayixhb3mec6dxnpccaq47by5ni",
    "uri": "at://did:plc:pi6woz4d47bkuws673w2il2r/app.bsky.feed.post/3mpfrqp25xjy2"
  },
  "path": "/t/ghc-proposal-top-level-io-initialized-bindings/14328#post_1",
  "publishedAt": "2026-06-29T05:09:20.000Z",
  "site": "https://discourse.haskell.org",
  "tags": [
    "github.com/ghc-proposals/ghc-proposals",
    "Top-level IO initialized bindings (#766)",
    "brandonchinn178",
    "+176\n-0",
    "",
    "Top-level mutable state",
    "Can NOINLINE fail to prevent inlining?"
  ],
  "textContent": "github.com/ghc-proposals/ghc-proposals\n\n####  Top-level IO initialized bindings (#766)\n\n`master` ← `brandonchinn178:top-level-io`\n\nopened 04:46AM - 29 Jun 26 UTC\n\n\n\n            brandonchinn178\n          \n\n\n+176\n-0\n\n\n[Rendered](https://github.com/brandonchinn178/ghc-proposals/blob/top-level-io/pr…oposals/0766-top-level-io.rst)\n\nThis has been a long-standing discussion, as documented at the Top-level mutable state page in the Haskell Wiki. After discussion in Can NOINLINE fail to prevent inlining?, this is my attempt at the problem.\n\nThe core of my proposal is:\n\n  * `OPAQUE` is better than `NOINLINE` for this idiom, but it’s not obvious that one should use `OPAQUE` over `NOINLINE`\n  * One must use `unsafePerformIO`, but it’s not actually unsafe if one uses `OPAQUE`. You lose ordering guarantees with regard to other IO actions, but that’s no more unsafe than `hGetContents`.\n  * `foo :: %TopLevelIO (IORef Int); foo = newIORef 0` is actually semantically sound and safe, provided the compiler respect the modifier\n\n",
  "title": "GHC Proposal: Top-level IO initialized bindings"
}