[Python-ideas] Add 'composable' decorator to functools (with @ matrix multiplication)
Erik Bray
erik.m.bray at gmail.com
Wed May 6 16:10:22 CEST 2015
On Wed, May 6, 2015 at 9:20 AM, Ivan Levkivskyi <levkivskyi at gmail.com> wrote:
> Dear all,
>
> The matrix multiplication operator @ is going to be introduced in Python 3.5
> and I am thinking about the following idea:
>
> The semantics of matrix multiplication is the composition of the
> corresponding linear transformations.
> A linear transformation is a particular example of a more general concept -
> functions.
> The latter are frequently composed with ("wrap") each other. For example:
>
> plot(real(sqrt(data)))
>
> However, it is not very readable in case of many wrapping layers. Therefore,
> it could be useful to employ
> the matrix multiplication operator @ for indication of function composition.
> This could be done by such (simplified) decorator:
>
> class composable:
>
> def __init__(self, func):
> self.func = func
>
> def __call__(self, arg):
> return self.func(arg)
>
> def __matmul__(self, other):
> def composition(*args, **kwargs):
> return self.func(other(*args, **kwargs))
> return composable(composition)
>
> I think using such decorator with functions that are going to be deeply
> wrapped
> could improve readability.
> You could compare (note that only the outermost function should be
> decorated):
>
> plot(sorted(sqrt(real(data_array)))) vs. (plot @ sorted @ sqrt @ real)
> (data_array)
>
> I think the latter is more readable, also compare
>
> def sunique(lst):
> return sorted(list(set(lst)))
>
> vs.
>
> sunique = sorted @ list @ set
>
> Apart from readability, there are following pros of the proposed decorator:
>
> 1. Similar semantics as for matrix multiplication.
> 2. Same symbol for composition as for decorators.
> 3. The symbol @ resembles mathematical notation for function composition: ∘
>
> I think it could be a good idea to add such a decorator to the stdlib
> functools module.
In the astropy.modeling package, which consists largely of collection
of fancy wrappers around analytic functions,
we used the pipe operator | (that is, __or__) to implement function
composition, as demonstrated here:
http://docs.astropy.org/en/stable/modeling/compound-models.html#model-composition
I do like the idea of using the new @ operator for this purpose--it
makes sense as a generalization of linear operators,
and it just looks a little more like the circle operator often used
for functional composition. On the other hand
I'm also fond of the choice to use |, for the similarity to UNIX shell
pipe operations, as long as it can't be confused with
__or__. Point being something like this could be implemented now with __or__.
I think this is simple enough that it doesn't need to be in the
stdlib, especially if there are different ways people
would like to do this. But I do like the idea.
Erik
More information about the Python-ideas
mailing list