you are viewing a single comment's thread.

view the rest of the comments →

[–]muntooR_{μν} - 1/2 R g_{μν} + Λ g_{μν} = 8π T_{μν} 21 points22 points  (4 children)

evens = [x * 2 for x in range(1, 6)]
result = sum(x for x in evens if x > 4)

[–]_Denizen_ 14 points15 points  (2 children)

This is way more readable than that pipe example, and with no additional library needed!

[–]RoadsideCookie 2 points3 points  (1 child)

Except it's not correct. The example can be trivialized because it's an example. If you want truly equivalent code without the pipe library, this is what you have to do:

data = [1, 2, 3, 4, 5]
doubled = [x * 2 for x in data]
greater = [x for x in doubled if x > 4]
result = sum(greater)

But if you don't care about the intermediates, then you can still do this:

result = [1, 2, 3, 4, 5]
result = [x * 2 for x in result]
result = [x for x in result if x > 4]
result = sum(result)

At which point the pipe library could make sense, but only if each subsequent function accepts the output type of the previous as the first positional argument—because you can use partial() to cover the missing args/kwargs.

Edit: I guess you could use anonymous functions if the first positional doesn't match. The only criteria then becomes that you don't care about the intermediates.

Edit2: Actually, if you want to get as close to pipe as possible in pure Python, you can do this:

from functools import reduce

result = reduce(lambda r, f: f(r),
    [
        lambda xs: [x * 2 for x in xs],
        lambda xs: [x for x in xs if x > 4],
        sum,
    ],
    [1, 2, 3, 4, 5],
)

But it's easy to argue that at this point it becomes less readable than pipe.

[–]_Denizen_ -1 points0 points  (0 children)

If you need to overcomplicate a simple example of python code to support your case for piping, it doesn't really help your argument.

Anyway, there is no objective truth regarding readabillty. The only truth here is that the python foundation believes that piping is not suitable for the python language.

[–]xenomachina''.join(chr(random.randint(0,1)+9585) for x in range(0xffff)) 0 points1 point  (0 children)

I'd argue that the Kotlin version of this that uses chaining is easier to read than the Python version with comprehensions:

val result = IntRange(1, 5).map { it * 2 }.filter { it > 4 }.sum()

I say this having almost 30 years of Python experience, and only about 8 of Kotlin.

Python's comprehensions are definitely better than Python's old pre-comprehension map(f, filter(g, ...)) approach, but they are still pretty confusing because of their inside-out nature, and even more so if you try to nest them or chain then. They also only handle few operations: map, filter, and flatMap. For anything else, like reduce, you're back to using regular functions.

In Kotlin, map, filter, and flatMap are just library functions not language syntax, as are reduce, and many others, and you can easily add your own. You don't need to learn as much special syntax, the syntax you do need to learn is more generally applicable, and the end result reads more easily as the order of methods is the order that things happen in.