Static pointers (Haskell Unfolder #53)

Will be streamed live today, 2026-01-21, at 1930 UTC.

Abstract:

“Static pointers” are references to statically known values, and can serialized independent of the type of the value (even if that value is a function), so that you can store them in files, send them across the network, etc. In this episode we discuss how static pointers work, and we show how we can use the primitive building blocks provided by ghc to implement a more compositional interface. We also briefly discuss how the rules for static pointers will change in ghc 9.14.2 and later.

15 Likes

Nice, I really enjoy this format of chat about practical topics.

2 Likes

If I’m not mistaken, polymorphic recursion is another reason why contexts can’t be static in general, right? For a function like:

polyRecurse :: Semigroup a => Int -> a -> a
polyRecurse 0 a = a
polyRecurse n a = sconcat $ polyRecurse (n-1) (NonEmpty.singleton a)

If we asked GHC to conjure up a static Dict (Semigroup a), it simply couldn’t because the a changes based on the recursion depth and so it keeps building a Semigroup dictionary dynamically for each depth.

Yes, true. This would be the case even for simpler examples:

foo :: Eq a => ..

bar :: Ord a => ..
bar = .. foo ..

We’d need to project out the Eq dictionary from Ord.

Either way, you’d need some kind of compositionality, something along the lines of what I sketched in the episode, although other variants are possible too of course. Non-composable StaticPtr is quite limited in its applicability.

1 Like

If you had to reimplement cloud Haskell today, would you use static pointers again?