> Anyway, I'll not push my pet peeve further :) (Though I do think it's an important peeve :).
Why not? If you have a good idea, push it. Hmm. So your proposal is: - When declaring a type T, specify it as a "non-updatable type" - A thunk of type T is call-by-name So in let foo = f 200 in g foo foo We'd expect (f 200) to be evaluated as many times as `g` evaluates either argument. Right? What about let bar:: Maybe T = Just (f 200) ] in ... Is bar call-by-name? Somehow wrapping in Just shouldn't change too much? Simon On Tue, 3 Feb 2026 at 08:25, Edsko de Vries <[email protected]> wrote: > I think there *is* a better answer: I think (but this will require > careful consideration) that the way is is to be able to mark certain types > as "never update thunks of this type". > > Anyway, I'll not push my pet peeve further :) (Though I do think it's an > important peeve :). > > -E > On 2/2/26 11:06, Simon Peyton Jones wrote: > > PS. If you'll allow me to be cheeky for a moment: if you did want a much >> more fundamental problem to sink your teeth into, may I interest you in the >> need for call-by-name in Haskell (as opposed to call-by-need)? I've been >> writing and talking about this for almost 10 years now ( >> https://well-typed.com/blog/2016/09/sharing-conduit/, HIW 2023, in >> Seattle, IFL 2024, ..; > > > The question of when to share and when to recompute is indeed a hard one. > I wrote about it in my 1987 book > <https://simon.peytonjones.org/slpj-book-1987/>, Chapter 23. I know of > no automated solution. Lacking that we need > > - Tools for identifying the problem > - Ways of saying what we want in those cases > > The `oneShot` primitive allows you to say "use call by name for this > lambda"; we use that in GHC. You didn't mention it in your post. > > I wish I had a better answer! > > Simon > > > On Sat, 31 Jan 2026 at 06:15, Edsko de Vries <[email protected]> wrote: > >> Hi Simon, >> >> The main pain point you identify is the "parallel set of instances". I >> wonder if there a design that could automate that? I think we discussed >> something along those lines years ago but I have fully paged it out. >> >> Also I wonder if there are enough compelling applications to justify it. >> Or if a good solution would unlock new applications. >> >> I'm pretty sure that that is a solvable problem, but honestly I don't >> think it's currently worth spending a lot of effort on it, given the >> unfortunately low adaption of static pointers. If you did want to improve >> the situation with static pointers, I think a more low hanging fruit would >> be to make StaticKeys more stable: across recompilation (with source code >> changes), across platforms, etc. I think that would make static pointers a >> bit more useful when deployed in a Cloud Haskell-like scenario, and perhaps >> spark some more interest. >> >> PS. If you'll allow me to be cheeky for a moment: if you did want a much >> more fundamental problem to sink your teeth into, may I interest you in the >> need for call-by-name in Haskell (as opposed to call-by-need)? I've been >> writing and talking about this for almost 10 years now ( >> https://well-typed.com/blog/2016/09/sharing-conduit/, HIW 2023, in >> Seattle, IFL 2024, ..; I also semi co-supervised a masters student on this >> topic), but I think nothing much has really changed yet. I think is an >> important problem (it affects real code that people write today) and very >> foundational (I don't know of any solutions to it, other than hacks like >> https://hackage.haskell.org/package/dupIO, our revival of Joachim's old >> package). I was going to send you my slides for my IFL talk but actually I >> think they don't make much sense without the accompanying presentation. If >> this at all sounds of interest, let me know and I can try to write down a >> summary of the problem (also happy to have a call if that's preferable). >> >> Have a good weekend :) >> >> Edsko >> >> warm good wishes >> >> Simon >> >> On Wed, 21 Jan 2026 at 17:43, Edsko de Vries <[email protected]> >> wrote: >> >>> Hi Simon, >>> >>> I'll look out for the Unfoldr episode -- if you remember do send me a >>> link >>> >>> The link is >>> https://www.youtube.com/watch?v=Mc3liw0EoIY&list=PLD8gywOEY4HaG5VSrKVnHxCptlJv2GAn7&index=54 >>> ; it will air live tonight at 7:30pm GMT, 8:30pm CET, and will be available >>> at the same link thereafter. >>> >>> -Edsko >>> >>> >>> On 1/9/26 16:21, Simon Peyton Jones wrote: >>> >>> Great thanks Edsko -- v helpful. >>> >>> By the way, I am not entirely sure why the proposal mentions the >>>> IsStatic class explicitly, but I just wanted to mention that it is >>>> really quite useful; I declare two instances in my Unfolder episode :) >>> >>> >>> The proposal mentions IsStatic only because I wanted to give the >>> expansion that GHC performs. I agree that it's useful, but it's really >>> orthogonal to the proposal. >>> >>> I'll look out for the Unfoldr episode -- if you remember do send me a >>> link >>> >>> Thanks again >>> >>> Simon >>> >>> >>> On Fri, 9 Jan 2026 at 12:25, Edsko de Vries <[email protected]> >>> wrote: >>> >>>> Hi Simon, >>>> >>>> Apologies for my slow reply. It's been nearly 15 years (!) since I >>>> wrote distributed-process and distributed-static (fun fact: it was my >>>> first task when I joined Well-Typed) and I felt I needed to set aside some >>>> time to properly page everything back in, as I haven't really used static >>>> pointers ever since (somewhat sadly..). I realize that the proposal how now >>>> been written and accepted, so this email comes too late in a way, but I >>>> finally had some time now to look at this properly. In hindsight, the >>>> proposal is simple enough, but I didn't realize that at the time. >>>> >>>> Anyway. The proposal is fine with me :) I seems to me that it's no more >>>> than a minor inconvenience to the programmer. I have now prepared a Haskell >>>> Unfolder episode (which will likely be the next episode we air, episode >>>> #53) on static pointers, where I discuss the primitive building blocks >>>> provided by ghc, and show how we can implement some compositional >>>> infrastructure around that (including some thoughts on type classes, which >>>> I believe you and I discussed a very long time ago). I'll also mention the >>>> proposal and the upcoming changes in 9.14.2 (warning) and 9.16 (change >>>> implemented). I tried building it with your branch (wip/T26718) and >>>> that all worked fine. I also added one module in which your branch issues >>>> the warning expect, and that seemed good also. >>>> >>>> By the way, I am not entirely sure why the proposal mentions the >>>> IsStatic class explicitly, but I just wanted to mention that it is >>>> really quite useful; I declare two instances in my Unfolder episode :) >>>> >>>> -Edsko >>>> On 11/19/25 13:02, Simon Peyton Jones wrote: >>>> >>>> Thanks Laurent and Mathieu >>>> >>>> *Edsko, Duncan, Facundo*: do you have any views? >>>> >>>> I have now written a GHC proposal >>>> <https://github.com/ghc-proposals/ghc-proposals/blob/wip/spj-static/proposals/0000-simplify-static.rst>. >>>> Could you add your thoughts to it? I think it's a no-brainer myself, but >>>> we should go through the proper process. >>>> >>>> Do any of you know people I should consult? Eg authors of libraries >>>> that use StaticPtrs? >>>> >>>> Thanks >>>> >>>> Simon >>>> >>>> >>>> >>>> On Fri, 7 Nov 2025 at 21:18, Simon Peyton Jones < >>>> [email protected]> wrote: >>>> >>>>> 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. >>>>>> 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 >>>>>> >>>>>> 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]
