
On Fri, Nov 26, 2021 at 07:40:43PM +0000, Paul Moore wrote:
On Fri, 26 Nov 2021 at 14:39, Raimi bin Karim <raimi.bkarim@gmail.com> wrote:
So this is more of a heartfelt note rather than an objective one — I would love my fellow Python programmers to be exposed to this mental model, and that could only be done by implementing it in the standard library.
I'm somewhat ambivalent about this pattern. Sometimes I find it readable and natural, other times it doesn't fit my intuition for the problem domain. I do agree that helping people gain familiarity with different approaches and ways of expressing a computation, is a good thing.
I don't think that even the most mad shell-scripting fanboi would say that pipelining is the One True software pattern and we should solve all problems that way :-) Collection pipelines are a natural and readable solution to *some* problems, not all, but in Python code it is difficult to use collection pipelines, so we end up writing the code backwards using function-call syntax. # The algorithm: filter, process, sort, print # data | filter something | process arg | sort | print # In Python: print(sort(process(filter(data, something), arg)))
I get your point that putting this functionality in a 3rd party library might not "expose" it as much as you want.
I fear that we don't yet have a good sense of the right syntax for this and how it will interact with the rest of Python syntax. As much as I love pipelines, I think that it's too early to push for this feature in the language. We need more experiments with syntax and functionality first. To me, the most natural syntax looks like this: value | function *args, **kwargs equivalent to `function(value, *args, **kwargs)` but of course we've already used the pipe for bitwise-or and set intersection. `>>` would be another equally good operator. I don't really like `|>` as an operator. If we were to invent a new operator, I'd prefer `->`. We can experiment by providing a wrapper class that takes a function, method or other callable and gives them a `__ror__` method for the pipe, and a `.p` (for partial) method for the partial application: value | Wrapper(function).p(*args, **kwargs) --> partial(function, *args, **kwargs)(value) That's sufficient for experimentation, but needing that wrapper adds too much friction. Ultimately nobody is going to use this idiom to its full potential until it works with arbitrary functions and callables without the wrapper. And by experiment, I don't mean experiment in the stdlib. I think that, like pathlib, this needs a few years of development outside the stdlib to mature. https://www.python.org/dev/peps/pep-0428/
Sorry - I don't have a good answer for you here. But I doubt you'll find anyone who would be willing to help you champion this for the stdlib.
I would be willing to help design an API and write a PEP but I would *not* champion it for 3.11. I think that a premature attempt to add it to the language would doom it to premature rejection. -- Steve