Also from the Zen: Â flat is better than nested. Â One of the aspects of
flatter call trees and object hierarchies is that I hit the bottom
(language features or the standard library) sooner, and I "should"
already have the language and its standard library in my brain. Â That
said, I also tend to break my programs into layers, but I do try to make
each layer as thin as possible (but no thinner).
I agree with your opinion about keeping the abstraction layers
shallow, but in my view high-order and helper functions do not
comprise a new abstraction layer. For example in Lisp, using map,
reduce (fold), or any other high-order function is just like using
for, or while in a normal imperative language.
Another example is the simple Observer pattern. How many think of
it as a new layer? Instead anytime we see a method that is named
add_listener we already have an idea of what it does... So we could
say that in FP world there are some patterns that involve "delegating
control" to them.
And also I would like to point out that "hitting the language
sooner", means to know every function in the standard Python library
(which is by far uncomprehensible, its huge) and most of the times you
also need the documentation. And if we go this path, when debugging we
could use a smart IDE, which should show as tool-tip-text for function
names their documentation, and in this way all we have to do to
understand a particular function is just to point it out.
Ciprian.
  Although you have a point -- that of being hard to comprehend by
average programmers -- but this doesn't mean it is a wrong (as in ugly)
solution... Also, with respects, but the "pythonic" solution involving
generators (or iterators) and "zip" or "all" function -- although I
appreciate it as it comes close to FP -- is not what I would call
readable and understandable by non-guru programmers...
I finally got it through my thick head that I've been *doing* functional
programming with [*nix] shells and pipes for years, well back into my non-
guru days.
Dan