<div dir="ltr"><div><div><div>Dear Guido,<br><br></div>My original idea was to make the composable functions auto-curried (similar to proposed here <a href="http://code.activestate.com/recipes/52902-function-composition/">http://code.activestate.com/recipes/52902-function-composition/</a> as pointed out by Steve) so that<br></div><br>my_fun = square @ add(1)<br>my_fun(x)<br><br>evaluates to <br><br></div>square(add(1,x))<br><br></div><div class="gmail_extra"><br><div class="gmail_quote">On 6 May 2015 at 17:48, Guido van Rossum <span dir="ltr"><<a href="mailto:guido@python.org" target="_blank">guido@python.org</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr">I realize this is still python-ideas, but does this really leave functions with multiple arguments completely out of the picture (except as the first stage in the pipeline)?<br></div><div class="gmail_extra"><br><div class="gmail_quote"><div><div class="h5">On Wed, May 6, 2015 at 8:42 AM, Erik Bray <span dir="ltr"><<a href="mailto:erik.m.bray@gmail.com" target="_blank">erik.m.bray@gmail.com</a>></span> wrote:<br></div></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div><div class="h5"><span>On Wed, May 6, 2015 at 11:21 AM, Ivan Levkivskyi <<a href="mailto:levkivskyi@gmail.com" target="_blank">levkivskyi@gmail.com</a>> wrote:<br>
> Dear Erik,<br>
><br>
> Thank you for the link! I agree that this idea is too raw for stdlib (there<br>
> are problems with many argument functions, keyword arguments, etc.)<br>
> Concerning the shell | vs. matrix @ I think it is a good idea to have<br>
> both... but with different order.<br>
> I mean in shell logic f | g means g (f (x)), while for matrix multiplication<br>
> f @ g means f(g(x)).<br>
> The former is probably more natural for people with more "programming"<br>
> background, while the latter is more natural for people with a "scientific"<br>
> background.<br>
> We could now do good for both, since we now have a new operator.<br>
<br>
</span>Absolutely! I've found that it takes a little work sometimes for<br>
scientific users to wrap<br>
their heads around the<br>
<br>
g | f<br>
<br>
syntax. Once Python 3.5 is out I might add support for "f @ g" as<br>
well, though I'm wary<br>
of having more than one way to do it. Worth trying out though, so<br>
thanks for the idea.<br>
<span><font color="#888888"><br>
Erik<br>
</font></span><div><div><br>
> On 6 May 2015 at 16:10, Erik Bray <<a href="mailto:erik.m.bray@gmail.com" target="_blank">erik.m.bray@gmail.com</a>> wrote:<br>
>><br>
>> On Wed, May 6, 2015 at 9:20 AM, Ivan Levkivskyi <<a href="mailto:levkivskyi@gmail.com" target="_blank">levkivskyi@gmail.com</a>><br>
>> wrote:<br>
>> > Dear all,<br>
>> ><br>
>> > The matrix multiplication operator @ is going to be introduced in Python<br>
>> > 3.5<br>
>> > and I am thinking about the following idea:<br>
>> ><br>
>> > The semantics of matrix multiplication is the composition of the<br>
>> > corresponding linear transformations.<br>
>> > A linear transformation is a particular example of a more general<br>
>> > concept -<br>
>> > functions.<br>
>> > The latter are frequently composed with ("wrap") each other. For<br>
>> > example:<br>
>> ><br>
>> > plot(real(sqrt(data)))<br>
>> ><br>
>> > However, it is not very readable in case of many wrapping layers.<br>
>> > Therefore,<br>
>> > it could be useful to employ<br>
>> > the matrix multiplication operator @ for indication of function<br>
>> > composition.<br>
>> > 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<br>
>> > wrapped<br>
>> > could improve readability.<br>
>> > You could compare (note that only the outermost function should be<br>
>> > decorated):<br>
>> ><br>
>> > plot(sorted(sqrt(real(data_array)))) vs. (plot @ sorted @ sqrt @ real)<br>
>> > (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<br>
>> > 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<br>
>> > composition: ∘<br>
>> ><br>
>> > I think it could be a good idea to add such a decorator to the stdlib<br>
>> > functools module.<br>
>><br>
>> In the astropy.modeling package, which consists largely of collection<br>
>> of fancy wrappers around analytic functions,<br>
>> we used the pipe operator | (that is, __or__) to implement function<br>
>> composition, as demonstrated here:<br>
>><br>
>><br>
>> <a href="http://docs.astropy.org/en/stable/modeling/compound-models.html#model-composition" target="_blank">http://docs.astropy.org/en/stable/modeling/compound-models.html#model-composition</a><br>
>><br>
>> I do like the idea of using the new @ operator for this purpose--it<br>
>> makes sense as a generalization of linear operators,<br>
>> and it just looks a little more like the circle operator often used<br>
>> for functional composition. On the other hand<br>
>> I'm also fond of the choice to use |, for the similarity to UNIX shell<br>
>> pipe operations, as long as it can't be confused with<br>
>> __or__. Point being something like this could be implemented now with<br>
>> __or__.<br>
>><br>
>> I think this is simple enough that it doesn't need to be in the<br>
>> stdlib, especially if there are different ways people<br>
>> would like to do this. But I do like the idea.<br>
>><br>
>> Erik<br>
><br>
><br>
</div></div></div></div><div><div>_______________________________________________<br>
Python-ideas mailing list<br>
<a href="mailto:Python-ideas@python.org" target="_blank">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></div></div></blockquote></div><span class="HOEnZb"><font color="#888888"><br><br clear="all"><br>-- <br><div>--Guido van Rossum (<a href="http://python.org/~guido" target="_blank">python.org/~guido</a>)</div>
</font></span></div>
</blockquote></div><br></div>