Dear Laurent, Duncan, Mathieu, Facundo, Edsko I have spent a little while digging into *static pointers* recently. See my post below. I wonder if you have any comments on my proposal?
Do you know anyone else I should consult? Thanks! Simon On Fri, 7 Nov 2025 at 18:13, Simon Peyton Jones (@simonpj) < [email protected]> wrote: > Simon Peyton Jones <https://gitlab.haskell.org/simonpj> created an issue: > #26556 <https://gitlab.haskell.org/ghc/ghc/-/issues/26556> > > Static pointers are not properly implemented. For example: > > - #26545 <https://gitlab.haskell.org/ghc/ghc/-/issues/26545> > - #24464 <https://gitlab.haskell.org/ghc/ghc/-/issues/24464> > - #24773 <https://gitlab.haskell.org/ghc/ghc/-/issues/24773> > > among others. Moreover, the implementation is very messy, scattered about > in FloatOut and elsewhere. > > Let's fix it. > <#m_5415477730196602759_discussion>Discussion > > I embarked on what I thought would be a simple refactor to > > - Identify static bindings in the type checker > - Promote them to top level desugarer > > thereby avoiding all the terribly painful static-form-floating stuff that > been an ongoing source of breakage and irritation. > > Sadly it was not as simple as I had thought. Merge request !14994 > <https://gitlab.haskell.org/ghc/ghc/-/merge_requests/14994> is my work in > progress > > - > > At first it seems simple: given static e > - When typechecking e ensure that all its free variables are top-level > defined > - When desugaring, move e to top level > > Apparently simple! > - > > *Complication 1*. e might generate constraints. We don't want to solve > those from locally-bound Givens, because they'll be out of scope when we > promote to top level. > > Solution: wrap the constraints in an implication with SkolInfo of > StaticFormSkol; and in the constraint solver zap all Givens when > walking inside such an implication. That was done in > > commit 39d4a24beaa7874a69ffdc1528ca160818829169Author: Simon Peyton Jones > <[email protected]>Date: Tue Sep 30 23:11:19 2025 +0100 Build > implication for constraints from (static e) This commit addresses #26466, by > buiding an implication for the constraints arising from a (static e) form. > The implication has a special ic_info field of StaticFormSkol, which tells > the constraint solver to use an empty set of Givens. > > So that complication wasn't at all bad. > - > > *Complication 2*. What if we have > > f x = let y = reverse "hello" in ...(static (y++y))... > > The free vars of the static are just {y}, and y is morally-top-level. > It in turn has no free variables. > > Sadly (as it turns out) GHC tries to accept this case. When looking at > the defn of y (with no static in sight yet) the typechecker marks it > at a "static binding", meaning that it too can (and indeed must) be floated > to top level. > > So if the desugarer moves the static to the top level, it must move y > too. And that means it must mark the typechecked binding in some way, so > the desugarer can identify it. Not so hard, but there is quite a bit of new > plumbing. > - > > *Complication 3*. But what if y's RHS generates constraints, which use > Givens (or solved dictionaries, which are very similar) from its context. > E.g. > > f x = let p = x+1::Int; y = 2+3::Int in ... > > Now there may be a d :: Num Int lying around from dealing with p, and y > may use it. Oh no! Now that'll be out of scope if we move y to top > level. > > Plausible solution: use them same mechanism for static bindings as we > did for static e expressions. That is, build an implication constraint > whose SkolInfo says "zap Givens". This turned out to be considerably harder > to implement than it was for Complication 1. > - > > *Complication 4*. What if y is not generalised, perhaps because of the > Monomorphism Restriction? e.g. > > f :: Num a => a -> blahf x = let y = 3+3 in (x+y, static( ..y.. )) > > Now y is monomorphic and really does use the dictionary passed to f. > So it really cannot appear in the static. Somehow y really isn't > static after all. We must reject this program. Not only is it an > implementation mess (Complications 1,2,3 are already imposing quite a > signficant implemenation burden) but it becomes pretty hard to explain to > the programmer just which uses of static are OK and which are not. > > What a swamp. At this point I threw up my hands and wrote this summary > > <#m_5415477730196602759_proposal>Proposal > > To me the solution is clear: the rule should be > > - *in static e, all the free vars of e should be bound at top level* > > That is a nice simple rule; it is easy to explain and easy to implement. > It is also what the user manual says! > > In retrospect, by addressing Complication 2 I was trying too hard! (And > this extra feature is entirely undocumented.) I thought that I could deal > with Complication 2 using the same mechanism as the one that deals with > MonoLocalBinds. But I was wrong. > > Making this change could perhaps break some programs. They would all be > easy to fix, by moving bindings for any free variables to top level. But > note that the status quo is not stable: it has bugs e.g #24464 > <https://gitlab.haskell.org/ghc/ghc/-/issues/24464>, #26545 > <https://gitlab.haskell.org/ghc/ghc/-/issues/26545>. What we have is at > attempt to be clever that is simply wrong. > > — > View it on GitLab <https://gitlab.haskell.org/ghc/ghc/-/issues/26556>. > You're receiving this email because of your activity on gitlab.haskell.org. > Unsubscribe > <https://gitlab.haskell.org/-/sent_notifications/4b29fc65ccdc21e95267b66fdfb679af/unsubscribe> > from this thread · Manage all notifications > <https://gitlab.haskell.org/-/profile/notifications> · Help > <https://gitlab.haskell.org/help> >
_______________________________________________ ghc-devs mailing list -- [email protected] To unsubscribe send an email to [email protected]
