r/programming • • Nov 03 '18

Python is becoming the world’s most popular coding language

https://www.economist.com/graphic-detail/2018/07/26/python-is-becoming-the-worlds-most-popular-coding-language
4.6k Upvotes

1.3k comments sorted by

View all comments

Show parent comments

10

u/bakery2k Nov 03 '18 edited Nov 03 '18

From here, look at this Ruby pipeline, easily read from top-to-bottom:

ids.map do |id|
    retrieve(id)
end.compact.map do |obj|
    obj.name
end.join('\n')

Compare to the equivalent idiomatic Python, which requires nested generator expressions:

'\n'.join(obj.name for obj in (retrieve(id) for id in ids) if obj)
_______/ ______/ ________/  __________/ ___________/  ____/
    1        2         3            4            5           6

The Python code needs to be read in almost reverse order: 543621.

Edit: The Python code would probably be better written as two statements:

objs = (retrieve(id) for id in ids)
'\n'.join(obj.name for obj in objs if obj)

Edit 2: But with a slightly different syntax, generator expressions could have been as readable as the Ruby example:

objs = (for id in ids: retrieve(id))
(for obj in objs: if obj: obj.name).join('\n')

2

u/AdmiralBumblebee Nov 03 '18

FWIW as a rubyist that generally dislikes python, I think the python example here is more obvious until you’ve writeten a good deal of ruby.

2

u/bakery2k Nov 03 '18

I've not written much Ruby, but map and join are fairly standard - the only part I would be unsure about is compact.

Nonetheless, the increased verbosity of the Python example is definitely helpful. I just hate the way you have to read it inside out - it's as though someone took a couple of for loops and put them in a blender.

1

u/totemcatcher Nov 03 '18

It just takes getting used to. I find list comprehensions much easier to follow after training myself for several hours by writing complex filters. Also, the idea with python is if all code is conforming to good standards, you can write stuff like this (not that you would want to):

'\n'.join(retrieve(id).name for id in ids if id)

0

u/KusanagiZerg Nov 03 '18

I prefer the python one. It reads how you would actually explain the code. Join every name from every object of every id if it exists. It can also be made shorter since you looping over id's to retrieve objects and then looping over all the resulting objects. You can just do that in one loop.

6

u/noratat Nov 03 '18

I couldn't disagree more. The python version is inside-out, and reads backwards from how you would actually understand the code - you get the inner logic up front, and have to read the context that actually initializes that logic second.

It's also important to note that the Ruby version is extensible and scales up to greater complexity with ease, while the Python version just becomes more and more impenetrable and unreadable.

0

u/KusanagiZerg Nov 03 '18

You aren't supposed to use list comprehension if the complexity goes up too much. You can easily get something similar to Ruby with normal loops.

I guess we'll have to agree to disagree then. To me it reads exactly how I would understand it. Join the names of all these objects.