4 ms·
I think it should be stressed that most languages (except maybe bash I guess) can’t provide the kind of compositionality that Haskell does. This is because Has
by dan-robertson 6y ago
I think it should be stressed that most languages (except maybe bash I guess) can’t provide the kind of compositionality that Haskell does.
This is because Haskell’s lazy evaluation allows these compositions to do an asymptotically appropriate amount of work. Consider this Haskell:
xs = [1..20]
p n = if n < 13 then even n else p n
ys = take 5 . filter p . drop 3 $ xs
main = print ys
If a strict language were being used then the processing would be as follows:
1. drop 3 ys is [4..20]
2. When computing filter p [4..20], everything is ok up to 12, but computing p 13 goes to an infinite loop.
3. We never get a result to compute take 5 of.
Because Haskell is lazy, it will not try to compute p 13 and so can do the right amount of work.
Perhaps a more reasonable example would be that if the list xs were really long, a strict program would have to evaluate p against every element before taking the first 5 results (so it would take linear time if p were constant time) while a lazy program would only need to compute p on enough elements to collect 5 results.
Common Lisp was designed for older, slower computers than Haskell and to be able to make programs which were reasonably efficient. It also had strict evaluation and so with this context, the extra arguments to many functions for special cases (which lots of people didn’t like) or the combined iteration of loop (which lots of people didn’t like) make a lot more sense.
- sukilot 6y agoSince bash and the Unix core utils are written in C, I strongly challenge your claim that "most languages" can't do stream processing. You don't have to have a lazy language to implement a lazy data type.
- bollu 6y agoThe difference is between pervasive laziness (laziness by default) v/s laziness by opt-in. If you have laziness by opt-in, then most parts of the language will not opt-in [from prior experience with, say, racket which also has lazy streams]. It's the pervasive and efficient compilation of laziness in Haskell which makes it actually useful to write lazy programs. Now, am I a fan of writing lazy programs? No, I find the upshot of referential transparency gained by laziness to be overshadowed by the warts it brings --- lack of a good debugging experience, tie-the-knot semantics being fragile, etc. I'd rather live in a strict total programming language. But one cannot "handwave" away laziness in haskell that easily by saying "you can emulate it in $STRICT_LANGUAGE". By the exact symmetric argument, one can emulate strict code inside haskell: just use `ST` or `IO`. But very rarely does one see whole libraries written strictly, because this style of code doesn't compose with the (default) laziness and purity in haskell.