{
"$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"
}