Need feedback about exposing an operator overloading in a module

Hi everybody, Long long time ago, I wrote thehttps://pypi.python.org/pypi/pipe Python module, TL;DR: a 6 lines of code decorator enabling infix syntax. Long time ago someone came to speak to me on IRC advising me to speak about it here, but I was still blocked in my mind about the exposed/leaked `|` operator overload. For me, a module should never expose an operator overload, because it may lead to unpredicted/unnatural/surprising behavior. But I may be wrong. Recently I was thinking about my pipe module and got an idea: What about exposing a single function instead of a whole bunch of operator-overloaded functions ? Like Pipe (because I can't spot a real name for the moment but need one for the example) and translate from: fib() | pp.where(lambda x: x % 2 == 0) | pp.take_while(lambda x: x < 4000000) | pp.add to Pipe(fib()).where(lambda x: x % 2 == 0) .take_while(lambda x: x < 4000000) .add().data It's a bit more dense but still far more readable than the classic suffix notation: pp.add(pp.take_while(lambdax: x < 4000000, pp.where(lambda x: x % 2 == 0, fib()))) (I explicitly prefixed by `pp.` to explicityly show that using the `|` operator we have to import either the module or every used functions, but using Pipe we do not have to) For clarity, where are the two implementations (Doctests permiting you to compare usability of both): Actual Pipe module: https://github.com/JulienPalard/Pipe/blob/master/pipe.py Pipe module with a function instead of operator overloading: https://github.com/JulienPalard/Pipe/blob/less_intrusive/pipe.py So a few questions: 1) Do you think, like me, that exposing a `|` overload is bad ? 2) In the less intrusive version, do you think, like me, that .register, Pipe(...), and .data are too much ? 3) Do you want to see something permitting infix notation in Python standard library ? Bests, -- Julien Palard

On 10/20/2014 12:42 PM, Julien Palard wrote:
I find this very readable.
I think this is also readable, although you need to surround the whole thing with parens or end the first two lines with '\'.
Complete agreement here. :)
So a few questions:
1) Do you think, like me, that exposing a `|` overload is bad ?
I do not see that as a problem, but without using it I can't know for sure.
2) In the less intrusive version, do you think, like me, that .register, Pipe(...), and .data are too much ?
I don't see a `.register` in the example, but I don't think Pipe and .data are inappropriate.
3) Do you want to see something permitting infix notation in Python standard library ?
No opinion. Although method chaining isn't strongly supported in the stdlib. -- ~Ethan~

Julien Palard wrote:
Modules don't expose operator overloads, types do. The idea that different types respond to operators in different ways is fundamental to Python, and in general I don't see anything wrong with making use of that. I do agree it's something that should be used sparingly, and most of the time a named method is much better. But I wouldn't say it should *never* be done. -- Greg

On 10/20/2014 3:42 PM, Julien Palard wrote:
I think the best is current idiomatic python: import itertools as it def fibg(): a,b = 0, 1 while True: yield a a,b = b, a+b evenfib = filter(lambda x: not x % 2, fibg()) print(sum(it.takewhile(lambda x: x < 4000000, evenfib)))
4613732
Two lines instead of three, with meaning clear. I am a fan of abstraction by naming and like breaking paragraphs up into sentences, and suites into statements.
1) Do you think, like me, that exposing a `|` overload is bad ?
No.
3) Do you want to see something permitting infix notation in Python standard library ?
Not especially. More persuasive use case needed. -- Terry Jan Reedy

On 10/20/2014 12:42 PM, Julien Palard wrote:
I find this very readable.
I think this is also readable, although you need to surround the whole thing with parens or end the first two lines with '\'.
Complete agreement here. :)
So a few questions:
1) Do you think, like me, that exposing a `|` overload is bad ?
I do not see that as a problem, but without using it I can't know for sure.
2) In the less intrusive version, do you think, like me, that .register, Pipe(...), and .data are too much ?
I don't see a `.register` in the example, but I don't think Pipe and .data are inappropriate.
3) Do you want to see something permitting infix notation in Python standard library ?
No opinion. Although method chaining isn't strongly supported in the stdlib. -- ~Ethan~

Julien Palard wrote:
Modules don't expose operator overloads, types do. The idea that different types respond to operators in different ways is fundamental to Python, and in general I don't see anything wrong with making use of that. I do agree it's something that should be used sparingly, and most of the time a named method is much better. But I wouldn't say it should *never* be done. -- Greg

On 10/20/2014 3:42 PM, Julien Palard wrote:
I think the best is current idiomatic python: import itertools as it def fibg(): a,b = 0, 1 while True: yield a a,b = b, a+b evenfib = filter(lambda x: not x % 2, fibg()) print(sum(it.takewhile(lambda x: x < 4000000, evenfib)))
4613732
Two lines instead of three, with meaning clear. I am a fan of abstraction by naming and like breaking paragraphs up into sentences, and suites into statements.
1) Do you think, like me, that exposing a `|` overload is bad ?
No.
3) Do you want to see something permitting infix notation in Python standard library ?
Not especially. More persuasive use case needed. -- Terry Jan Reedy
participants (4)
-
Ethan Furman
-
Greg Ewing
-
Julien Palard
-
Terry Reedy