[Python-ideas] Function composition (was no subject)
Koos Zevenhoven
koos.zevenhoven at aalto.fi
Sun May 10 17:15:58 CEST 2015
On 10.5.2015 5:56, Steven D'Aprano wrote:
[...]
>> You could in addition have:
>>
>> spam @ eggs @ cheese @ arg # equivalent to spam(eggs(cheese(arg)))
>>
>> arg | spam | eggs | cheese # equivalent to cheese(eggs(spam(arg)))
>>
>> Here, arg would thus be recognized as not a function.
> No. I think it is absolutely vital to distinguish by syntax the
> difference between composition and function application, and not try to
> "do what I mean". DWIM software has a bad history of doing the wrong
> thing.
>
> Every other kind of callable uses obj(arg) to call it: types, functions,
> methods, partial objects, etc. We shouldn't make function composition
> try to be different. If I write sqrt at 100 I should get a runtime error,
> not 10.
>
> I don't mind if the error is delayed until I actually try to call the
> composed object, but at some point I should get a TypeError that 100 is
> not callable.
>
That is in fact a part of why I added a function call () to the sketch
in my recent post (extended partial operator, there using ->). This way,
the composition operator would never do the actual call by itself, but
instead make a partial. But I admit that (sqrt at 100)() still would give
10, not the runtime error you want (which may indeed cause problems with
callable arguments). It only solves half the problem.
Another way to feed the left-to-right | composition from the left would
of course be
(feed(x) | spam | eggs | cheese)() # feed would be just def feed(x):
return x
But I'm not sure I like it. Luckily, (cheese @ eggs @ spam)(x) does not
have this problem. However, if cheese, eggs and spam were matrix
transformations, one would write
cheese @ eggs @ spam @ x
But perhaps numpy would want to bridge this gap with extended behavior
(allow calling numpy functions with @ or "calling a matrix
transformation" with () ). Or perhaps not :).
-- Koos
More information about the Python-ideas
mailing list