small edit to article

This commit is contained in:
Tony Hannan 2011-07-18 16:00:02 -04:00
parent f8b8886f53
commit 82a846e918

View file

@ -36,7 +36,7 @@ Haskell expressions are [lazily evaluated](http://en.wikipedia.org/wiki/Lazy_eva
cond bool a b = case bool of True -> a; False -> b cond bool a b = case bool of True -> a; False -> b
x = cond True 1 (2 `div` 0) x = cond True 1 (2 `div` 0)
`x` evaluates to 1 instead of failing on divide-by-zero because the last arg is not evaluated in this case. Lazy evaluation facilitates user-defined control structures, like `cond` above. It also enables infinite data structures, like `ones = 1 : ones` (infinite list of 1's) or `[1,2..]` (infinite sequence), because later elements are only created on demand. Finally, lazy evaluation facilitates modularity because you can separate functionality knowing that an inner operation will only proceed when its outer operation demands it. Intermediate data structures (eg. lists) won't be built in full then later consumed, instead each element will be built on demand and immediately consumed thus using constant space. This behavior is similar to piping programs together in Unix. To get similar behavior in an eager language, you could use an imperative generator for intermediate operations, but this is more complex, not pervasive, and not pure. `x` evaluates to 1 instead of failing on divide-by-zero because the last argument is not evaluated in this case. Lazy evaluation facilitates user-defined control structures, like `cond` above. It also enables infinite data structures, like `ones = 1 : ones` (infinite list of 1's) or `[1,2..]` (infinite sequence), because later elements are only created on demand. Finally, lazy evaluation facilitates modularity because you can separate functionality knowing that an inner operation will only proceed when its outer operation demands it. Intermediate data structures (eg. lists) won't be built in full then later consumed, instead each element will be built on demand and immediately consumed thus using constant space. This behavior is similar to piping programs together in Unix. To get similar behavior in an eager language, you could use an imperative generator for intermediate operations, but this is more complex, not pervasive, and not pure.
However, a drawback of lazy evaluation (and thus Haskell) is hard-to-predict space usage. For example, we know the above `reduce` function requires (stack) space linear to the size of the list, but what about its [tail recursive](http://en.wikipedia.org/wiki/Tail_recursion) version, which uses constant stack space. However, a drawback of lazy evaluation (and thus Haskell) is hard-to-predict space usage. For example, we know the above `reduce` function requires (stack) space linear to the size of the list, but what about its [tail recursive](http://en.wikipedia.org/wiki/Tail_recursion) version, which uses constant stack space.