5 ms·
1: When I hit the opening bracket, I don't know whether I'm looking at an array literal or a comprehension. I have to read ahead a few tokens to disambiguate.
by ezrast 10y ago
1: When I hit the opening bracket, I don't know whether I'm looking at an array literal or a comprehension. I have to read ahead a few tokens to disambiguate.
2: When I hit `transform(bar)`, I don't know what `bar` is either. I have to jump forward to disambiguate again.
3: Once I hit `for bar in` I realize I'm in a comprehension, but that's still not enough to figure out what `transform(bar)` is acting on. I have to read to the end of the `if` condition, then backtrack to the beginning.
bonus reason: why not `list(baz)`? Is there actually some logic to when Python uses methods and when it uses global functions? If so, please tell me.
another bonus reason: when I was learning Python, I found the keyword reuse genuinely confusing. I would try to write for loops like `for x in my_list if condition(x):` and couldn't figure out why it didn't work because I knew I had seen that syntax somewhere before.
Now, your particular example isn't that bad, but if you make it just a little more complicated you get something like this aberration:
foo = [transform(bar) if bar.property else bar for bar in baz.list() if condition(bar)]
Nothing will convince me that you're not a mutant if you think that's clear and concise.
Meanwhile, over in Ruby-land, we write this:
baz.each.select{ |bar|
condition(bar)
}.map{ |bar|
bar.property ? transform(bar) : bar
}
Which to me parses very easily into meat-brain logic, in small chunks, with a single pass:
-Start with `baz`
-Consider each item
-Select only those `bar`s that meet `condition`
-Map each `bar` to...
-`transform(bar)` when `property` is true; itself otherwise (okay, natural language actually more closely resembles Python-style ternaries here. Sue me).
P.S. apologies for the multiple edits; I am an HN formatting noob.
- dragonwriter 10y ago> When I hit the opening bracket, I don't know whether I'm looking at an array literal or a comprehension. I have to read ahead a few tokens to disambiguate. All research I have seen says that proficient readers of a language read closer to a line at a time than a token at a time, so I suspect that not really a problem so much as a rationalization of aesthetic preference. > bonus reason: why not `list(baz)`? Is there actually some logic to when Python uses methods and when it uses global functions? list is a built-in type, and (as is usually the case for Python types) list() is the type constructor. There are other global functions in Python and there is room for debate over whether they make sense over methods, but constructors for built-types are pretty clear. baz.list() is a method on baz. Assuming baz is iterable, list(baz) is valid, it's just different than baz.list().