fold. By examining the origins of
reduce, we saw that it is an abstraction over a particular recursive pattern of control flow. Further,
reducecan be readily defined in Python.
However, it is easy to find cases where
reduceworks well for a functional programming language but poorly in Python. In essence,
reduceis an abstraction over a common pattern for functional programming languages that is uncommon in imperative programming languages like Python. Instead, a much narrower selection of Python procedures map well onto the
By examining control flow patterns actually used in Python, a more appropriate higher order procedure1,
app, was identified as an alternative to
reduce. Several common control flow patterns cannot be captured by
app, so a dual
genprocedure was also defined.
gen, we can define many functions to process or create iterators. However, an important question remains: should we use
gen? I'd have to say that it isn't worthwhile. Both
genare abstractions over imperative patterns, depending crucially on side effects. As a consequence, it is of equal importance to understand the order in which, say,
appprocesses the elements of an iterator. Thus,
appfails to provide any conceptual benefit over just using a
forloop—in contrast, functional programming with
map, and other higher order functions lets you ignore the order in which things are done.
That said, I use and define higher order procedures all the time in Python. I just define them as (generator) functions using imperative constructs like
whileloops. Also, like the
itertoolsmodule, my higher order procedures typically take iterators as arguments or return them as results. So long as iterators only need to be used once, this looks a lot like functional programming. Really, it is closer to dataflow programming.
Having an effective alternative to
reduceis relatively unimportant for this iterator-intensive programming style. Far more useful would be higher order procedures that simplify composing multiple procedures taking and returning iterators. The overall result should be more like constructing a shell pipeline instead of the extensive nesting of procedure calls currently seen.
1 For clarity, I distinguish here between higher order functions and higher order procedures. Functions should really be mathematical functions, i.e., no side effects, while procedures are more general.