On 2014-03-06, at 08:29 , Stephen J. Turnbull email@example.com wrote:
On 2014-03-05, at 22:51 , Greg Ewing firstname.lastname@example.org wrote:
On 2014-03-04, at 23:31 , Greg Ewing email@example.com wrote:
That comes at the expense of making *everything* a thunk until its value is needed [in Haskell].
Of course not, Haskell allows explicitly forcing a thunk and the compiler/runtime pair can use strictness analysis and not create thunks in the first place.
That doesn't seem fair to me. "Explicitly forcing" by definition means the programmer has decided the value is needed
No, it means the programmer wants the value to be strictly evaluated (this is generally a space optimisation). It has no impact on program behavior (assuming infinite resources, one issue of accumulating thunks is the risk of OOM if they remain live but unevaluated).
and "strictness analysis" is an optimization, not part of the language definition. Am I missing something?
No? It just demonstrates that not everything is a thunk in haskell, there are both thunks and strict values living around in the runtime, and that's not visible in the type system.
Consider that a thunk is a deferral of an expression's evaluation, why would said expression's evaluation happen more than once? The only thing which changes is *when* the actual evaluation happens.
Are thunks guaranteed not to leak out of the scope of the containing expression, so assignment is impossible?
I'm not sure I understand the question.
If they can leak, the thunk would be an object
I think that's just one possible implementation, a thunk could also be some sort of reference indirection, a tagged pointer, or a deeply integrated proxy-ish object.
and in Python "assigning" it to a "variable" actually just creates a reference. Evaluation could memoize the thunk's value ("evaluation only happens once") or reevaluate the thunk each time its value is requested. Either seems potentially surprising to me.
Memoization makes sense if you think of the thunk as the closure of a computation that conceptually takes place at definition time. I'm not sure if in the use cases for thunks it really makes sense to "close" the thunk at evaluation time, but it seems like a plausible interpretation to me.
I find it the most *useful* definition: for the other one we already have functions and I'm not sure thunks would have much use as shorter arguments-less functions.
It also has the property that "client" code (code receiving thunks without necessarily being aware of it) remains valid and unsurprising in that
a = foo b = foo assert a is b
remains true regardless of `foo` being a thunk (the only difference being that if `foo` is a thunk it may remain unforced throughout).