Great post. This is one of my biggest pet peeves with Ruby and languages like it; they encourage developers to "show off" by using the most esoteric features they can find (even better if these features use weird symbols). Compared to a language like Python that has few neuroses, the same developer writes much less readable code. The post may have been better if the author included a Python sample that does the same…
Something like the following: capitalize = lambda word: "{}{}".format(word[0].upper(), word[1:]) new_string = ' '.join(map(capitalize, long_string.split(' '))) or: new_string = ' '.join(["{}{}".format(word[0].upper(), word[1:]) for word in long_string.split(' ')]) is much clearer and simpler to me, because it explains the intention of the code: split the string into words, map each word to it's capitalized version, t…
I dislike your first example because
a) imo, the lack of spacing makes it harder to see what's going on. it's more obvious that something is being iterated in a for loop with a new indentation level than in the map function.
b) it depends on the Python-specific implementation of lambda. The behavior of a lambda varies substantially from language to language and lambdas are used rarely enough that it's pretty likely someone who doesn't spend all day every day in Python is going to have to go back and look up the specific behavior. The syntax is much less clear than a full function definition.
In my opinion, it's much easier to read code like:
def capitalize(str):
return "{}{}".format(str[0].upper(), str[1:])
for word in long_string.split(' '):
captizalize(word)
...
This makes it much more obvious what's going on, and it should be readable to anyone with a passing knowledge of Python, and possibly anyone with a knowledge of programming languages in general. Invocation of map and lambda in this case only make the intent of the program more obscure.I'm not saying that map or lambda are never appropriate to use; sometimes they are. But I don't think it's wise to use them when more basic, universal language constructs do an equally adequate job, especially if the only benefit is "fewer lines of code".
The second example is just a list comprehension form of my original example, which IMO is less readable for much the same reasons. If you're not super familiar, you'll need to go back and look up list comprehensions. There is no spacing to make it obvious that something particular is being iterated or branched.
I understand that ultimately, ease of reading comes down to what style one is most familiar with, which makes it subjective, as you said. But I think there is a stronger rational basis for always preferring the simplest construct that adequately performs the function, which is that in the general case, there is less need to refer back to docs, less possibility of unexpected behavior, and less possibility of strange performance issues.