[Python-ideas] [RFC] draft PEP: Dedicated infix operators for matrix multiplication and matrix power

Andrew Barnert abarnert at yahoo.com
Wed Apr 9 04:40:42 CEST 2014


On Apr 8, 2014, at 16:00, Michael Mitchell <epsilonmichael at gmail.com> wrote:

> I'm not confident I can make that case very well, but I suppose I can try :).
> 
> There do seem to be some hand-rolled composition functions in various Github repositories: https://github.com/search?l=python&q=%22def+compose%22&ref=searchresults&type=Code 
> 
> I'm not sure why a composition operator has never been added to the functools library, but I'd make the observation that a composition function wouldn't be much less verbose than in my earlier lambda example. A infix binary operator, however, would be quite more concise, especially so when chaining multiple functions.

A few problems have been raised with this.

The big one is that it's not clear what it means to compose functions unless they take and return a single value. While you could make it call g(*f(x)) to pass multiple values, that makes it no longer work with single-value functions.

Functional languages deal with that by having equally compact ways to do all kinds of other general higher-order tasks, like partialing functions and sectioning operators (or they just use currying to make all functions partial), flipping arguments, raising functions (like a map that returns a function over an iterable, instead of taking an iterable in the map call), etc. Python has nothing but partial, it's not that compact, and it's buried in functools.

Also, some people find that code using higher-order functions more than necessary usually doesn't look very pythonic. All kinds of things that are done by building up a higher-order function and then calling it in a language like Haskell are usually instead done by chaining or imperatively calling functions in Python. This could lead to a "more than one way to do it" situation, or just to code that's harder to understand without thinking it through. (I personally don't find this argument very compelling, but then it's hard for me to put myself in the shoes of people who never use functional languages, so that may not mean much. And I think Guido is one of the people who finds it compelling.)

Both left-compose and right-compose are perfectly valid operations, and the one that looks obviously right to novices is the opposite of the one that's obviously right (or at least more often) to experts.

Finally, compose and matrix multiplication are false cognates. Matrices are operations on vectors under multiplication--the same operator used for composing those operations. Functions are operations on values under calling--a completely different operator than @.

Finally, it would help to have a real use case instead of just filter(a @ b, x). Presumably b is some function from elements of x to some other type, and a  is a predicate function from that type to bool... but it's hard to think of useful functions (as opposed to expressions you'd have to wrap in lambda anyway) that fit that bill off the top of my head.

None of these means the idea is impossible or useless, just that it's less obvious a win than it looks at first.

> There's also precedent to the @ symbol being associated with functions, i.e. decorator syntax. Decorators are callables that accept callables and return callables, which parallels the infix definition of accepting two callables and returning a callable.
> 
> 
> On Tue, Apr 8, 2014 at 2:17 PM, Nathaniel Smith <njs at pobox.com> wrote:
>> It's been raised a few times, but the problem is that there's no evidence that anyone actually needs a short way to perform composition - notice the composition operation's never even been added to functools. If you do want to make that case though then there's nothing stopping you :-)
>> 
>> On 8 Apr 2014 22:10, "Michael Mitchell" <epsilonmichael at gmail.com> wrote:
>>> I haven't been following this thread too closely, so please stop me if this has been covered, but has overloading the @ operator as function composition been considered yet?
>>> 
>>> An example would be 
>>> 
>>> filter(a @ b, lst)
>>> 
>>> as opposed to
>>> 
>>> filter(lambda x: a(b(x)), lst)
>>> 
>>> 
>>> On Sun, Apr 6, 2014 at 6:51 PM, Nathaniel Smith <njs at pobox.com> wrote:
>>>> On Mon, Apr 7, 2014 at 12:20 AM, Steven D'Aprano <steve at pearwood.info> wrote:
>>>> > On Sun, Apr 06, 2014 at 11:02:00PM +0100, Nathaniel Smith wrote:
>>>> >> On Sun, Mar 16, 2014 at 1:05 PM, Nick Coghlan <ncoghlan at gmail.com> wrote:
>>>> >> > Aye, but at the moment it makes sense to wait and see if there is even
>>>> >> > an argument to be had - Nathaniel may decide that even after reviewing
>>>> >> > the question seriously, he doesn't want to propose a right associative
>>>> >> > operator :)
>>>> >>
>>>> >> And indeed, that does seem to be the way things have worked out :-).
>>>> >>   http://mail.scipy.org/pipermail/numpy-discussion/2014-April/069834.html
>>>> >
>>>> > That's a shame in one way -- for anyone using operator overloading to
>>>> > define their own DSL, there's only ** if you want a right-associative
>>>> > operator to overload. Still, that's an extremely marginal, and
>>>> > hypothetical, use-case. Left-associative it is.
>>>> >
>>>> > Was that the last blocker for the PEP?
>>>> 
>>>> Pretty much. Just posted to python-dev:
>>>>    https://mail.python.org/pipermail/python-dev/2014-April/133791.html
>>>> 
>>>> -n
>>>> 
>>>> --
>>>> Nathaniel J. Smith
>>>> Postdoctoral researcher - Informatics - University of Edinburgh
>>>> http://vorpus.org
>>>> _______________________________________________
>>>> 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/
> 
> _______________________________________________
> 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/
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/python-ideas/attachments/20140408/7348ed11/attachment.html>


More information about the Python-ideas mailing list