Don't get me wrong, I love closures, but all of these examples are basically as miserable as the "3.times" example.
"Oh, hey! We can replace a for loop doing addition with a fold, with only the added conceptual complexity of ensuring that (+) is an associative operator, and making sure that we don't accidentally blow our stack by unexpectedly recursing too far because we assumed the wrong evaluation order." (Which by the way his example does.)
I have never seen a non-trivial example of fold* (i.e. anything other than "+" or "*") that I didn't have to spend several seconds or minutes rewriting it (mentally or in typing) as a loop to figure out WTH it is doing.
f1 list = foldr (&&) True list -- && is logical and
f2 list = foldr (||) False list -- || is logical or
f3 list = foldl max (head list) (tail list)
f4 list = foldl min (head list) (tail list)
Do you consider them trivial, or too hard to understand without rewriting as a loop? Honest question.
I think if you use a non-associative function as an argument, then fold is hard to understand. But then an explicit loop won't help much.
I know exactly what you mean. The fact is, every single program you write is going to be executed by a little stateful machine ticking along. So if your programming language doesn't model such a machine and instead uses higher-order constructs, then I will have to mentally translate everything you write to make full sense of it.
> then I will have to mentally translate everything you write to make full sense of it.
But why? A SQL query or a Java/Python/whatever program might get translated to zillions of CMP and JMP instructions, but I see no reason why you should have to do that translation yourself in order to read the code. In fact that would practically preclude the use of any minimally high-level programming language.
"Oh, hey! We can replace a for loop doing addition with a fold, with only the added conceptual complexity of ensuring that (+) is an associative operator, and making sure that we don't accidentally blow our stack by unexpectedly recursing too far because we assumed the wrong evaluation order." (Which by the way his example does.)