It is.

However that doesn't give users the ability to solve this since -ffull-lazines allows GHC to potentially turn such a function into a thunk. One can disable full-laziness to avoid this, but you might like some things to be floated/shared and others to be constrained to a certain context rather than retaining them.

Even if GHC would leave the function itself one might end up with code like:

foo::Void#->T
foo =...
bar x y z =
letr =foo void#
in(f r,f r)

Now foo itself is a "non-updatable thunk". But we capture it's result in an updatable thunk. Hence the need for the non-updatable attribute to be transitive in some fashion.
Associating it with the return type might be one solution to address this.



On 03/02/2026 13:34, Tom Ellis via ghc-devs wrote:
Isn't a function of type `(# #) -> T` already (isomorphic to) a
"non-updatable thunk" of type T?

Tom

On Tue, Feb 03, 2026 at 11:43:48AM +0000, Simon Peyton Jones via ghc-devs wrote:
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

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".
_______________________________________________
ghc-devs mailing list [email protected]
To unsubscribe send an email [email protected]
_______________________________________________
ghc-devs mailing list -- [email protected]
To unsubscribe send an email to [email protected]

Reply via email to