You wrote:
> Good API designs can reduce loop complexity. For example, looping thru a
> DB result set (or cursor) can be as simple as:
>
> rs = openRS([criteria])
> while getNext(rs) {
> [loop contents]
> }
>
> What is there to screw up here?
For one thing, you haven't closed the cursor. :)
This is a perfect example of why abstracting common patterns of iteration into a higher-level API is a good idea. Namely, you need to get the fold function correct once, and then every future use of it will be correct. In this case, if you had an iteration function available you would not have accidentally created a resource leak.
People -- all people -- are bad at repetition and detail work. If we have to repeat even a trivial task, then we will screw it up. For a simple example, try quickly counting from 1 to 300 out loud without screwing up. I just tried it, and got up to 114 before stumbling over my words. Now consider that this task is much easier than writing even the simplest computer program.
This is why I am so hell-bent on abstracting the common patterns in my code. I know that I suck at detail work. Closures are a good thing because they let me build my program out of tested, interchangeable parts.