[Haskell-cafe] haskell in online contests
wren ng thornton
wren at freegeek.org
Sun Nov 29 01:11:38 EST 2009
> wow ok, I'm not even able to see why they're different in the desugared
They're different because case is strict binding (see caveat below)
whereas let is lazy binding. If we say,
let foo = big ugly computation in bar
Then if foo isn't used in bar, it'll never be computed. (Even if foo
occurs in bar, provided it occurs somewhere that won't be evaluated.)
Whereas if we say,
case big ugly computation of foo -> bar
Then we're forced to do the computation, regardless of whether foo is
used in bar. Actually, that's not entirely true. In this example,
because foo is a variable, the binding will be lazy; whereas if we
replaced foo with a (non-lazy) pattern then it'd be strict.
Part of the complication in explaining the exact details is because both
case and let can have patterns inside of the binding so the desugaring
process has to continue recursively. Also there're some details about
using let for defining recursive groups, which you can't do with case.
Also Haskell's syntax conflates defining functions with doing pattern
matching, so there's an extra step to separate functions using pattern
matching into the definition binding vs the pattern matching. In any
case, once you're done compiling you end up with a strict binding
operator (kind of like case) and a lazy binding operator (kind of like let).
When in doubt, try playing around with different definitions to see
whether they break when you pass in 'undefined'. There are also a few
papers out there on how the STG works under the covers.
More information about the Haskell-Cafe