While looking into parallel programming, and subsequently evaluation strategies, the question whether thunks are mutable came up. To give an example, let’s say I have the following code:
foo = 1 + 2 -- Thunk
bar = foo `seq` foo -- Evaluates foo
Calling seq when evaluating bar evaluates foo, giving bar the normal form value 3. Does this evaluation affect foo as well? That is, is the value of foo still 1+2 or is it 3 after evaluating bar?
The Haskell report only specifies that the evaluation order is “non-strict”, so either behavior would conform to the standard.
However, using lazy (“call by need”) evaluation, which involves sharing values in a way that makes thunks “mutable” as you describe, offers asymptotic improvements over “call by name” (that is, no sharing).
So in GHC (and probably most other reasonable implementations),
foowill become3after you force it for the first time. However, this is not mandated by the standard, which you should keep in mind.