On Wed, May 6, 2015 at 9:20 AM, Ivan Levkivskyi <levkivskyi@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-compos... 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