
On 7/3/06, Andrew Koenig <ark@acm.org> wrote:
I don't think "trivial" is the right word to use here, since it implies something that's of so little importance that it can be ignored. But the simple cases are precisely the ones where this wart hurts the most, so we can't ignore them.
I'd like to inject an example that might help make this discussion more concrete.
Consider the following function:
def for_each(seq, f): for i in seq: f(i)
I'm sure I've seen more than one instance of someone on comp.lang.python trying to do the equivalent of using a function such as this one to compute the sum of the elements of a sequence as follows:
def sum(seq): result = 0 def accum(i): result += i for_each(seq, accum) return result
and wonder why it doesn't work. Still odder, why it doesn't work and the following does:
def sum(seq): result = [0] def accum(i): result[0] += i for_each(seq, accum) return result[0]
Transforming the first definition of sum above into the second may be trivial, but only if you've encountered the technique before. Moreover, the first version of sum uses a technique that is more than 45 years old (!), as it was available to Algol 60 programmers.
Much though the Algol 60 tickles my nostalgia (it was my first programming language!) I don't think that it's a particularly strong argument. I like to think that we have better ways these days. I think you need to come up with a better motivating example; the above is particular un-idiomatic Python. It starts by defining a higher-order function for_each that has little to offer over writing an explicit for loop, and then uses this to motivate writing a simple operation (result += i) as a function instead so that it fits in the inconvenient for_each() API. I understand that both for_each() and accum() are just examples of more complicated functions, but I can't help thinking that the problem here only occurs for very *simple* functions in the place of accum(); a more complicated form of accum would likely be a bound method of a class instance which carries the state. A better way to decompose these kinds of problems is probably by using generators. The equivalent of for_each() would not take a function parameter but *yield* the successive values instead of calling f() with successive values; e.g.: def for_each(seq): for i in seq: yield i Then the sum() function could be written like this: def sum(seq): result = 0 for i in for_each(seq): result += i return result -- --Guido van Rossum (home page: http://www.python.org/~guido/)