Is readability always better?
September 30, 2022 -At the recent YOW Perth conference, Andy Marks & Pam Rucinque of Thoughtworks presented a thought-provoking talk on "Reviving the art of software design". As part of the talk they had a selection of different-but-functionally-identical implementations of a pangram-checking function, and attendees were asked to vote on which one was best.
The following implementation received the most votes (I note at its origin on exercism.io it’s the most popular solution there also):
export const isPangram = (input) => {
const inputLowered = input.toLowerCase()
return [..."abcdefghjklmnopqrstuvwxyz"]
.every(c => inputLowered.includes(c))
};
I can easily understand why people voted for it - I think it hews closely to most developers’ internal mental models of how to solve the problem, and we view it as the most ‘readable’ or ‘understandable’ implementation. It is also influenced by what we currently think of as good programming techniques, perhaps 10-15 years ago we would have seen a for
loop there instead.
However, I would posit this is not good code (or at least, that there are much better solutions out there). The reason is that I’ve introduced an intentional bug in the above version and I’m betting most readers didn’t spot it - I've dropped the i
out of the alphabet string, perhaps this was a fat-fingered delete when copying & pasting from StackOverflow. The function will now return false positives in a very small number of cases, however I suspect this code would make it through code review 9 times out of 10, and will probably pass all of the unit tests. (If you’d written property based tests you’d pick up the bug, but inexplicably most developers still aren’t writing these.)
What’s interesting to me is that we know honking great big magic string literals in code is bad design, but most people still chose this design anyway. I believe now we’ve had decades of indoctrination in the primacy of code readability, we may have reached a point where the perceived readability/understandability of code trumps every single other consideration, even when the code is qualitatively worse. Now I concede I’ve seen some pretty awful crimes against readability in an attempt to guard against obscure bugs (eg a lot of 90s-era coding standards), but I feel we could have lost balance here.