Migrated from One Billion Row challenge in Hs - #184 by rhendric, since it is diverging from the topic.
I agree that deepseq
is a tool with uses. Nonetheless, my claim is indeed very strong! There are few cases when I’ll make a claim that strong. There are so many complexities in the world of programming that I am open minded to the possibility that someone else can see something that I can’t. Regarding space leaks, however, I’ve investigated the area deeply enough for long enough (it’s been an interest of mine for probably ten years) that I am confident my conclusion is correct.
For comparison, another case I am confident about is that it is absolutely wrong to use Go-style product errors (Maybe Result, Maybe Error)
and absolutely right to use sum type errors Either Error Result
(another example of making invalid states unrepresentable). The difference between the case of space leaks and the case of errors is that using sum types for error handling has deeply percolated the Haskell community (and other languages besides) but making invalid laziness unrepresentable has not (I made a Twitter poll yesterday, and around 20% had heard of the notion).
To clarify my point, I was addressing the concern of a new user that Haskell experts cannot agree on the correct way to fix space leaks. It is really important that as a community we resolve this concern. One of the things that makes Haskell different from the vast majority of languages is laziness. I regularly see people dismiss Haskell because “laziness makes it impossible to reason about performance and space usage”. This claim is false and if we as a community fail to address it with a simple response then many people who could otherwise adopt and love Haskell will be put off from even trying.
The correct way to address all of the space usage aspect of that concern (i.e. space leaks) and part of the performance aspect is to make invalid laziness unrepresentable, just like if someone said “Haskell makes it impossible separate error states from normal return states” we’d say "no it doesn’t – make invalid states unrepresentable and replace your (Maybe Result, Maybe Error)
with Either Error Result
". Problem solved.
I did not say that force
has no uses at all, nor did I say that making invalid laziness unrepresentable fixes all space leaks (although I’ve never seen a case where it couldn’t). I said that for the particular program in question the correct approach is to make invalid laziness unrepresentable, and, for that particular program, force
is an incorrect approach (as is “sprinkling bang patterns”). I think that is the correct way to explain the situation to new users.
deepseq
is an important tool to have at your disposal, even if just to tryforce
-ing different things until you figure out which things to refactor.
Sure, that seems reasonable.
(But sometimes invalid laziness has to be representable; Haskell’s type system is very good at letting you express invariants through types but no type system is perfect at this.)
I don’t think I could ever refute such a general claim, although I’m not sure exactly what you’re referring to. Maybe Okasaki style data structures that use laziness in an essential way?
I invite anyone who sneers at
deepseq
to take a look at Fix space leak between modules during compilation by MonoidMusician · Pull Request #4517 · purescript/purescript · GitHub and recommend a better way to address that problem
Yes, I’m happy to help. What’s the easiest way to reproduce the problem? Is it this comment? Is there anything simpler? I’m unfamiliar with Purescript, let alone familiar with building its compiler.
deepseq
is a time leak machine! and many other languages have it built into their spec
I don’t understand what it means for other languages to have deepseq
built into their spec.