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

Ron Adam ron3200 at gmail.com
Fri Mar 14 18:05:43 CET 2014



On 03/14/2014 10:41 AM, Ron Adam wrote:
>
>
> On 03/14/2014 07:32 AM, Steven D'Aprano wrote:
>>> >AFAIK, other languages sometimes use ".*" for matrix multiplication (as
>>> >opposed to element-wise multiplication). Why not re-use that
>>> >convention? Would that lead to parsing difficulties?
>> "Syntax should not look like grit on Tim Peters' monitor."
>>
>> .* is, in my opinion, pretty ugly, and leads to even ugly
>> extensions:
>>
>> a .* b  # matrix multiplication
>> a .*= b  # in place matrix multiplication
>> a .** b  # matrix exponentiation
>> a .**= b  # in-place matrix exponentiation
>>
>> And it suffers from exactly the same lack of connection to matrix
>> multiplication as @ does: there is nothing about . that spells "matrix".
>>
>> It also has the problem that it could cause confusion with vector dot
>> product. Read out A .* B aloud and you get something that sounds like it
>> might mean dot product, "A dot times B".
>
> The best I can come up with is to use '^' instead of dot.
>
>     a ^* b  # matrix multiplication
>     a ^^ b  # matrix exponentiation
>
> Also two ^ together looks like a M.  It's not a strong association, but it
> may help some people remember what it's for.   Or the second one could be
> spelled... ^**, but I think the ^^ is cleaner.
>
>
> Question?  Is it possible for python to tell these apart at compile time?
>
>  >>> a = 6
>  >>> b = 4
>  >>> c = 8
>  >>> a^b
> 2
>  >>> a ^b c
>    File "<stdin>", line 1
>      a ^b c
>           ^
> SyntaxError: invalid syntax
>
> So that this later example does...
>
>       a.__use__(self, "b", c)
>
>
> The ^b is unrelated to the name b in the second case.  Or is this just not
> possible?

One more comment, if this idea is limited to only allow symbols that can't 
be seen in identifiers, then the conflict goes away also.  That's probably 
not an unreasonable restriction.


> If it could be done, then ...
>
>       a ^* b    -->     a.__use__(self, "*", b)
>       a ^^ b    -->     a.__use__(self, "^", b)
>
>
> Where the __use__ method is defined on a module level object.  (and not
> defined on builtin's as a general rule.)
>
>      def __use__(self, s, other):
>         if s == "*":
>            ...           # do matrix multiply
>            return result
>         elif s == "^":
>            ...           # do matrix exponentiation
>            return result
>         raise TypeError
>
>
>
> Anyway to make this work nicely?

I would of liked it to be more general, but this could work for just 
symbols.  It could also be extended to allow ^'string', at some later date.

Cheers,
     Ron



More information about the Python-ideas mailing list