<div dir="ltr"><div><div><div><div><div>Dear Andrew,<br><br></div>Thank you for pointing out the previous discussion, I have overlooked it. (Btw, I have found your post about the infix operators, that is a great idea).<br>Also, It turns out that astropy uses a very similar idea for function composition.<br><br></div>I agree that there are indeed to much ambiguities about the "right way", and thus it is not good for stdlib. However, implementing only one decorator as a third-party library is not good idea as well.<br></div>You are right that no one will install such library. Probably, it would be better to combine it with other functionality like @infix (via overloading __or__ or __rshift__), @auto_curry, etc.<br></div><br></div>Thank you for the feedback!<br><div><div><div><div><div><br></div></div></div></div></div></div><div class="gmail_extra"><br><div class="gmail_quote">On 6 May 2015 at 15:59, Andrew Barnert <span dir="ltr"><<a href="mailto:abarnert@yahoo.com" target="_blank">abarnert@yahoo.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">This was discussed when the proposal to add @ for matrix multiplication came up, so you should first read that thread and make sure you have answers to all of the issues that came up before proposing it again.<br>
<br>
Off the top of my head:<br>
<br>
Python functions don't just take 1 parameter, they take any number of parameters, possibly including optional parameters, keyword-only, *args, **kwargs, etc. There are a dozen different compose implementations on PyPI and ActiveState that handle these differently. Which one is "right"?<br>
<br>
The design you describe can be easily implemented as a third-party library. Why not do so, put it on PyPI, see if you get any traction and any ideas for improvement, and then suggest it for the stdlib?<br>
<br>
The same thing is already doable today using a different operator--and, again, there are a dozen implementations. Why isn't anyone using them?<br>
<br>
Thinking in terms of function composition requires a higher level of abstraction than thinking in terms of lambda expressions. That's one of the reasons people perceive Haskell to be a harder language to learn than Lisp or Python. Of course learning Haskell is rewarding--but being easy to learn is one of Python's major strengths.<br>
<br>
Python doesn't have a static optimizing compiler that can avoid building 4 temporary function objects to evaluate (plot @ sorted @ sqrt @ real) (data_array), so it will make your code significantly less efficient.<br>
<br>
Is @ for composition and () for application really sufficient to write point free code in general without auto-curried functions, operator sectioning, reverse compose, reverse apply, etc.? Most of the examples people use in describing the feature from Haskell have a (+ 1) or (== x) or take advantage of map-type functions being (a->b) -> ([a] -> [b]) instead of (a->b, [a]) -> [b].<br>
<br>
Sent from my iPhone<br>
<br>
> On May 6, 2015, at 06:15, Ivan Levkivskyi <<a href="mailto:levkivskyi@gmail.com">levkivskyi@gmail.com</a>> wrote:<br>
><br>
> Dear all,<br>
><br>
> The matrix multiplication operator @ is going to be introduced in Python 3.5 and I am thinking about the following idea:<br>
><br>
> The semantics of matrix multiplication is the composition of the corresponding linear transformations.<br>
> A linear transformation is a particular example of a more general concept - functions.<br>
> The latter are frequently composed with ("wrap") each other. For example:<br>
><br>
> plot(real(sqrt(data)))<br>
><br>
> However, it is not very readable in case of many wrapping layers. Therefore, it could be useful to employ<br>
> the matrix multiplication operator @ for indication of function composition. This could be done by such (simplified) decorator:<br>
><br>
> class composable:<br>
><br>
>     def __init__(self, func):<br>
>         self.func = func<br>
><br>
>     def __call__(self, arg):<br>
>         return self.func(arg)<br>
><br>
>     def __matmul__(self, other):<br>
>         def composition(*args, **kwargs):<br>
>             return self.func(other(*args, **kwargs))<br>
>         return composable(composition)<br>
><br>
> I think using such decorator with functions that are going to be deeply wrapped<br>
> could improve readability.<br>
> You could compare (note that only the outermost function should be decorated):<br>
><br>
> plot(sorted(sqrt(real(data_array)))) vs. (plot @ sorted @ sqrt @ real) (data_array)<br>
><br>
> I think the latter is more readable, also compare<br>
><br>
> def sunique(lst):<br>
>     return sorted(list(set(lst)))<br>
><br>
> vs.<br>
><br>
> sunique = sorted @ list @ set<br>
><br>
> Apart from readability, there are following pros of the proposed decorator:<br>
><br>
> 1. Similar semantics as for matrix multiplication.<br>
> 2. Same symbol for composition as for decorators.<br>
> 3. The symbol @ resembles mathematical notation for function composition: ∘<br>
><br>
> I think it could be a good idea to add such a decorator to the stdlib functools module.<br>
> _______________________________________________<br>
> Python-ideas mailing list<br>
> <a href="mailto:Python-ideas@python.org">Python-ideas@python.org</a><br>
> <a href="https://mail.python.org/mailman/listinfo/python-ideas" target="_blank">https://mail.python.org/mailman/listinfo/python-ideas</a><br>
> Code of Conduct: <a href="http://python.org/psf/codeofconduct/" target="_blank">http://python.org/psf/codeofconduct/</a><br>
</blockquote></div><br></div>