[Python-Dev] any support for a methodcaller HOF?

Bengt Richter bokr at oz.net
Fri Feb 3 16:16:23 CET 2006

On Fri, 03 Feb 2006 20:44:47 +1000, Nick Coghlan <ncoghlan at gmail.com> wrote:

>Michael Hudson wrote:
>> Alex Martelli <aleaxit at gmail.com> writes:
>>> I'll be glad to write a PEP, but I first want to check whether the
>>> Python-Dev crowd would just blast it out of the waters, in which case
>>> I may save writing it...
>> Hmm.
>>>>> funcTakingCallback(lamda x:x.method(zip, zop))
>>>>> funcTakingCallback(methodcaller("method", zip, zop))
>> I'm not sure which of these is clearer really.  Are lambdas so bad?
>> (FWIW, I haven't internalized itemgetter/attrgetter yet and still tend
>> to use lambdas instead those too).
If you are familiar with lambda, it's clearer, because the expression
evaluation is just deferred, and you can see that zip and zop are going
to be accessed at lambda call time. methodcaller could potentially hide
an alternate binding of zip and zop like lambda x, zip=zip, zop=zop:x.method(zip,zop)
So you have to know what methodcaller does rather than just reading the expression.
And if you want to customize with def-time (lambda eval time) bindings as well as
call arg bindings, you can't easily AFAICS.

BTW, re def-time bindings, the default arg abuse is a hack, so I would like to
see a syntax that would permit default-arg-like def-time function-local bindings without
affecting the call signature. E.g., if def foo(*args, **keywords, ***bindings): ...
would use bindings as a dict at def-time to create local namespace bindings like **keywords,
but not affecting the call signature. This would allow a nicer version of above-mentioned
   lambda x, zip=zip, zop=zop:x.method(zip,zop)
   lambda x, ***dict(zip=zip, zop=zop):x.method(zip,zop)
   lambda x, ***{'zip':zip, 'zop':zop}:x.method(zip,zop)
This could also be used to do currying without the typical cost of wrapped nested calling.

>I've been convinced for a while that the proliferation of features like 
>operator.itemgetter and attrgetter (and some uses of functional.partial) 
>demonstrate that the ability to defer a single expression (as lambda currently 
>allows) is a very useful feature to have in the language. Unfortunately that
<BTW>note that "deferring" is a particular case of controlling evaluation time.
The other direction in time goes towards reader macros & such.</BTW>
>utility gets overshadowed by the ugliness of the syntax, the mathematical 
>baggage associated with the current keyword, and the fact that lambda gets 
>pitched as an "anonymous function limited to a single expression", rather than 
>as "the ability to defer an expression for later evaluation" (the former 
>sounds like a limitation that should be fixed, the latter sounds like the 
>deliberate design choice that it is).
>At the moment it looks like the baby is going to get thrown out with the 
>bathwater in Py3k, but I'd love to be able to simply write the following 
>instead of some byzantine mixture of function calls to get the same effect:
>     funcTakingCallback(x.method(zip, zop) def (x))
>Consider these comparisons:
This looks a lot like the "anonymous def" expression in a postfix form ;-)
>   itemgetter(1)     <=> (x[1] def (x))
                      <=> def(x):x[1]
>   attrgetter('foo') <=> (x.foo def (x))
                      <=> def(x):x.foo
>   partial(y, arg)   <=> (y(arg) def)
                      <=> def(***{'arg':arg}):y()  # ?? (not sure about semantics of partial)
>So rather than yet another workaround for lambda being ugly, I'd rather see a 
>PEP that proposed "Let's make the syntax for deferring an expression not be 
>ugly anymore, now that we have generator expressions and conditionals as an 
>example of how to do it right".
I guess you can guess my vote is for anonymous def ;-)
>Guido was rather unenthused the last time this topic came up, though, so maybe 
>it isn't worth the effort. . . (although he did eventually change his mind on 
>PEP 308, so I haven't entirely given up hope yet).
Likewise ;-)

Bengt Richter

More information about the Python-Dev mailing list