
On Sun, Nov 28, 2021 at 05:28:58PM +0000, Evpok Padding wrote:
Hi,
All apologies if it has been clarified earlier, but if you dislike nested method calls what is wrong with operating on generators as in
```pycon
itr = (i**2 for i in range(8)) itr = (i-1 for i in itr if i > 0) list(itr) [0, 3, 8, 15, 24, 35, 48]
Nothing, and everything :-) Of course sometimes code is clearer when it is split over multiple statements, using named variables to hold intermediate results. But often code is *less* clear when it is split over multiple statements. That's why we have expressions: y = sqrt(3*(x+2) - 5) rather than being forced to perform one operation at a time: tmp = x + 2 tmp = 3*tmp tmp = tmp - 5 y = sqrt(tmp) and why we can chain methods of immutable objects: text.strip().lower().expandtabs().encode('utf-8') instead of being forced to perform one operation at a time. But beyond some certain level of complexity, it may be helpful to separate a complex expression into temporary steps. That's not going to change. Sometimes code is better when it is more terse, and sometimes when it is more verbose. An expressive language allows us to make the choice ourselves.
This covers chains of maps and filter, and everything provided by itertools. Granted, it does not offer lazy reduce and sort but these would not be very hard to implement, and since they need to consume the whole iterator anyway, it's not clear how useful they would be.
I don't understand how this thread, which is about pipelines of functions, has become fixated on *iterators*. You don't need lazy iterators to operate with a pipeline of functions, or chained methods. We often use method chains with non-lazy strings, and bash or other shells use pipelines of non-lazy functions on collections of data. Pipelines are syntax, not functionality. With pipe syntax, you can pipe anything into a function, whether it is a concrete collection, a lazy iterator, or a single atomic value. -- Steve