[Python-ideas] (no subject)

Andrew Barnert abarnert at yahoo.com
Wed May 6 21:51:29 CEST 2015


On May 6, 2015, at 08:05, Ivan Levkivskyi <levkivskyi at gmail.com> wrote:
> 
> Dear Andrew,
> 
> 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).

Well, nobody else seemed to like that idea, which may be a warning sign about this one. :)

> Also, It turns out that astropy uses a very similar idea for function composition.
> 
> 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.
> 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.

Actually, many of the implementations on PyPI are part of "miscellaneous functional tools" libraries that do combine it with such things. And they still have practically no users.

There are plenty of libraries that, despite being on PyPI and not mentioned anywhere in the standard docs, still have a lot of users. In fact, much of what's in the Python stdlib today (json, sqlite3, ElementTree, statistics, enum, multiprocessing, ...) started off that way. And there may be more people using requests or NumPy or Django than a lot of parts of the stdlib. "Nobody will use it unless it's in the stdlib" doesn't cut it anymore in the days of most Python installations including pip, the stdlib docs referencing libraries on PyPI, etc. If something isn't getting traction on PyPI, either people really don't want it--in which case there's nothing to do--or someone really needs to evangelize it--in which case you should start doing that, rather than proposing yet another implementation that will just gather dust.

Finally, I think you've ignored an important part of my message--which is probably my fault for not making it clearer. Code that deals in abstract functional terms is harder for many people to think about. Not just novices (unless you want to call Guido a novice). Languages that make it easier to write such code are harder languages to read. So, making it easier to write such code in Python may not be a win.

And the reason I brought up all those other abstract features in Haskell is that they tie together with composition very closely. Most of the best examples anyone can come up with for how compose makes code easier to read also include curried functions, operator sections, composing the apply operator itself, and so on. They're all really cool ideas that can simplify your logic--but only if you're willing to think on that more abstract plane. Adding all of that to Python would make it harder to learn. Not adding it to Python would make compose not very useful. (Which is why the various implementations are languishing without users.)

> Thank you for the feedback!
> 
> 
>> On 6 May 2015 at 15:59, Andrew Barnert <abarnert at yahoo.com> wrote:
>> 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.
>> 
>> Off the top of my head:
>> 
>> 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"?
>> 
>> 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?
>> 
>> The same thing is already doable today using a different operator--and, again, there are a dozen implementations. Why isn't anyone using them?
>> 
>> 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.
>> 
>> 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.
>> 
>> 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].
>> 
>> Sent from my iPhone
>> 
>> > On May 6, 2015, at 06:15, 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.
>> > _______________________________________________
>> > Python-ideas mailing list
>> > Python-ideas at python.org
>> > https://mail.python.org/mailman/listinfo/python-ideas
>> > Code of Conduct: http://python.org/psf/codeofconduct/
> 
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/python-ideas/attachments/20150506/a56a58b3/attachment.html>


More information about the Python-ideas mailing list