[Python-ideas] Function composition (was no subject)

Andrew Barnert abarnert at yahoo.com
Sun May 10 00:45:26 CEST 2015


On May 9, 2015, at 08:38, Ron Adam <ron3200 at gmail.com> wrote:
> 
> 
> 
> On 05/09/2015 03:21 AM, Andrew Barnert via Python-ideas wrote:
>>> >I suppose you could write (root @ mean @ (map square)) (xs),
> 
>> Actually, you can't. You could write (root @ mean @ partial(map,
>> square))(xs), but that's pretty clearly less readable than
>> root(mean(map(square, xs))) or root(mean(x*x for x in xs). And that's
>> been my main argument: Without a full suite of higher-level operators
>> and related syntax, compose alone doesn't do you any good except for toy
>> examples.
> 
> How about an operator for partial?
> 
>          root @ mean @ map $ square(xs)

I'm pretty sure that anyone who sees that and doesn't interpret it as meaningless nonsense is going to interpret it as a variation on Haskell and get the wrong intuition.

But, more importantly, this doesn't work. Your square(xs) isn't going to evaluate to a function, but to a whatever falling square on xs returns. (Which is presumably a TypeError, or you wouldn't be looking to map in the first place). And, even if that did work, you're not actually composing a function here anyway; your @ is just a call operator, which we already have in Python, spelled with parens.

> Actually I'd rather reuse the binary operators.  (I'd be happy if they were just methods on bytes objects BTW.)
> 
>          compose(root, mean, map(square, xs))

Now you're not calling square(xs), but you are calling map(square, xs), which is going to return an iterable of squares, not a function; again, you're not composing a function object at all.

And think about how you'd actually write this correctly. You need to either use lambda (which defeats the entire purpose of compose), or partial (which works, but is clumsy and ugly enough without an operator or syntactic sugar that people rarely use it).
> 
>          root ^ mean ^ map & square (xs)
> 
>          root ^ mean ^ map & square ^ xs ()
> 
> Read this as...
> 
>         compose root, of mean, of map with square, of xs

But that's not composing. The whole point of compose is that you can compose root of mean of mappings square over some argument to be passed in later, and the result is itself a function over some argument to be passed in later.

What you're doing doesn't add any new abstraction, it just obfuscates normal function application.

> Or...
> 
>          apply(map(square, xs), mean, root)
> 
>          map & square | mean | root (xs)
> 
>          xs | map & square | mean | root ()
> 
> 
> Read this as...
> 
>          apply xs, to map with square, to mean, to root
> 
> 
> These are kind of cool, but does it make python code easier to read?  That seems like it may be subjective depending on the amount of programming experience someone has.
> 
> Cheers,
>   Ron
> 
> 
> 
> 
> _______________________________________________
> Python-ideas mailing list
> Python-ideas at python.org
> https://mail.python.org/mailman/listinfo/python-ideas
> Code of Conduct: http://python.org/psf/codeofconduct/


More information about the Python-ideas mailing list