This is a counter-proposal to another suggestion about introducing a pipe operator in Python. It’s not meant for inclusion in the language. The goal is simply to explore the idea on its own. I’m not interested in debating hypotheticals.
Please keep the discussion focused on the proposal itself:
def add1(x):
return x + 1
2 |> add1 # 3; equivalent to add1(2)
def calc(x, y):
return x + y**2
2 |> calc(3) # 11; equivalent to calc(2, 3)
2 |> calc(..., 3) # 11; equivalent to calc(2, 3)
2 |> calc(3, ...) # 7; equivalent to calc(3, 2)
def gen(i):
for i in range(i):
yield i
5 |> gen |> print # prints 0 1 2 3 4 separated by newline
range(1, 4) |> iter |> gen |> print(end=' ') # prints 0 0 1 0 1 2 without newline
[1, 2, 3] |> print # prints [1, 2, 3]
range(100000000) |> print # prints range(0, 100000000)
range(100000000) |> iter |> print # not only prints all those numbers, but it uses almost no memory at all
The proposal is intentionally left without further explanation. Either the reader understands what’s going on, or the syntax is unclear.
I should have been clearer. I’m not in favor of including it in the language, but I’m open to discussing it here. This thread could serve as the platform for presenting arguments both against and in favor of its inclusion.
Not sure if it should be calc(2, 3) or calc(3, 2). The latter would be more in line with partial.
There were variants of Ellipsis placeholders in PyPI when I was researching potential directions for partial. There is quite a big inconvenience with arbitrary number of values on the left - it’s signature is unclear and such construct is unlikely to go through to standard library on its own as an independent component.
But this is same as current explorations in Introduce funnel operator i,e '|>' to allow for generator pipelines - #237 by sadaszewski - it seems to be a proposal for monolithic construct. For such, I believe the signature will never have to be inferred programatically (and typing could infer things from the whole construct), so not as big of an issue, but nevertheless - keeping things consistent whenever possible is of long term benefit IMO.
OK, so the syntax is unclear. Without the comments, I wouldn’t be able to understand what the syntax does. With the comments, I can see what each individual statement does, but I can’t infer a general rule for how |> behaves.
The only feedback I can give is that this is pointless in its current (underspecified) form.
Typing 3 characters instead of one is a major inconvenience. Default injection position (as the first argument) plays poorly with existing Python functions. Limitation to calls or callables on the RHS is a major inconvenience. This limitation allows to use just the callable name but don’t be fooled - this is translated into a call under the hood. As the others are saying, without a specification it’s not even possible to discuss it. Overall it feels like a “pipeline operator of the past century” not a pipeline operator of the future and as if the authors made all the worst possible choices at each and every junction. The lack of a magic method to override it is the nail in the coffin. It’s extremely limited compared to the state we achieved in the other thread. I am surprised it surfaced at this stage.
We’re not here to debate that. The design choices are well-suited to the language in question. The pipe operator works perfectly in Codon, but it doesn’t fit naturally in Python.