This is very sage advice.
This is very sage advice.
> Code is read many more times than it is written. Writing code costs something, but over time the cost of reading is often higher. Anyone who ever looks at a piece of code has to invest brain-power into figuring out what it does.[1]
This is also noted in PEP8:
> One of Guido's key insights is that code is read much more often than it is written. The guidelines provided here are intended to improve the readability of code and make it consistent across the wide spectrum of Python code. As PEP 20 says, "Readability counts".[2]
[1]: https://www.sandimetz.com/blog/2017/6/1/the-half-life-of-cod... [2]: https://www.python.org/dev/peps/pep-0008/#a-foolish-consiste...
Code smells draw the eye when debugging. Your brain wants the problem to be in the code that’s clearly “wrong”. So smelly code anywhere near common code paths has a huge cost compared to smelly code in some leaf function in an obscure feature.
One of the wisdoms of XP, I think. The code you touch the most should be the sanest.
I'm really curious how true this is. Partly because, if it really was read more than it is written, people would optimize to /write less/ of it - if you have to pick up everything you put on the floor ten times over, it will incentivize you to put fewer things on the floor in future. And people would say things about code which people say about writing, such as "you have to write for your audience", instead of the more common "it's either boolean readable or unreadable".
And partly because I suspect code is /skimmed over/ more than it is read; that is, people assume what it does, glance at its shape, then if there's no surprise triggered, move on.
I would be interested to know if anyone has studied what it means for code to be read, but my suspicions are that most code which works is almost never read, and most code which is read, is read because it doesn't work and therefore it will be self-selected to be poor code in some regard.
But then, I'm not a programmer working on a large codebase. Those of you who are, how much of it have you read in enough detail that you verified how it works - and no assuming that a method does what its name implies, or assuming that if it passes tests it must work, but actually verifying by studying it that it does what it should and that you understand it?
I mean in real life (when you don't have Guido to do it for you), if people are writing code you can't understand then you need to tell them to fix it. And many people don't like being told they need to rewrite their code because you can't understand it, so it leads to conflict and eventually you often need to fire people.
So yes, it's good advice, but by cleaning up engineering debt you're often going to take on a lot of team debt.
There are people who simply refuse to understand generics and/or stream APIs. Which are to (most) programmers more readable then the same logic being drawn out in a loop.
Meanwhile some other programmer would just write code golf and brag about it.
At the end of the day, it should be about enforcing a coding style that defines what you can or can't do. Adding final to all variable that can be final for instance is a great start.
How come so many people try to use code to show how smart they are?
My first CL at my first job out of college was writing a state machine at Google. I remember collapsing it into this dense, elegant representation by hinging on a couple of bits of state. It took me an extra half day, but I was really proud of the end result, and I remember being mildly put off by the request that I unroll it and make it explicit. Upon thinking about it for a bit, I decided it was entirely reasonable, and after a few more years at Google, I transformed into the kind of engineer insisting that every bit of code prioritize readability over everything else, in the absence of constraints like performance. Across the tech orgs and teams that I've run since, this has paid huge dividends. I'm writing a lot of tensorflow and C++ at a very fast-moving company working on a complex problem, and I don't know how anyone on my team would be productive at all without strictly prioritizing readability.
Being good at coding and having good engineering habits aren't the same skill, and the latter is about discipline and patience (and occasionally thinking like a dumber person), which are inherently less fun than unfettered technical challenges.
I’ve been thinking again lately about little bits I picked up via osmosis and my own early creative writing experiences. In fact I was just noting a couple weeks ago how refactoring resembles an exploratory writing exercise.
I think we need to embrace the creative writing similarities. Would we ever celebrate an author who published efficient, dense and cryptic text? Rarely.
One of the things we do want is someone who paints a clear picture in a few well chosen words. Another is to be inspired. Tricked or bored are not on that list.
We have ideas of a "grade 6 reading level", do we have such a scale for code? If not, why not?
Writing clever code doesn't mean it's being done for that reason. As the article notes, Guido himself agreed that in the early stages of developing a piece of software, such as in an early stage startup, it probably makes sense to write clever code, because you can get it done faster and therefore iterate faster on improving the code to meet user needs. At this stage very few people are working on the code (often just one), so communicating with other developers is not a big issue.
The need for making it maintainable comes later, when the product is mature and many more people are working on the code, so the need for clear communication becomes much stronger.
>We don’t see people writing books in acronyms or omitting words.
Math books written for mathematicians do this all the time.
I think it would be more accurate to say that we assume that other developers have the same amount of context about the problem as we do.
Going back and reading my own code from even a few months ago makes this very evident, as I frequently realize that I'd made various assumptions that required a much deeper level of understanding than I anticipated. The difficulty in providing a sufficient amount of context is readily apparent to me as I go back and fill in the gaps I unknowingly left.
And telling them their cleverness is hurting other people can be traumatic, for one or both parties.
I like being clever too. I’ve just sublimated that into more beneficial things like human factors.
I think that excuse falls over when you look at some old code you yourself wrote, and you find that you can't understand it.
That's presuming your smartness doesn't change much over time.
When I’m trying to add functionality of fix a bug, I’m going to read dozens and dozens of functions to winnow down to a handful of candidates.
Simple code can be filtered quickly and cheaply. Clever code requires contemplation. Which clears working memory.
Yes, I can understand your code. But I shouldn’t have to work for it.
If a critical service is experiencing growth and built on cryptic stuff, then the world may notice if no one can maintain it and it falls over.
when I write code for a concept i don't understand completely, it tends to be complex and cryptic. I'll go back to it after trying to understand the problem and the problem space more and be able to write simpler code.
When are you having fun reading someone else’s code? You’re usually there trying to solve a problem. Your plans for the day have gotten away from you. You may even be having a Bad Day. And this is at least doubly true for failing tests.
Take pity on the person.
An example that frequently occurrs is decomposing a large method into smaller methods. Okay, there are now more lines of code (due to adding method declarations), but what was really gained? The gain that can be had is identifying common use cases and factoring some of those methods out to utility classes that can be referenced from the same source file and others. This can be difficult to identify unless one learns to really look for these oppurtunities.
The approach I've been taking recently is presenting the idea as there's always a minimal level of abstraction, and code should try to achieve it. I'm interested to hear what others think about this.
Python not caring about the type of a parameter makes it easy to share code too.
It's tricky, isn't it? The original quote was about "clever code" versus "maintainable code", but they are not orthogonal: it's possible to write code that's more maintainable (because it's harder to use incorrectly) at the cost of being more clever (because you need to learn more of the language or standard library to understand it). One person's "more maintainable" is going to be another person's "too clever" — you're going to get a bunch of different opinions on where the line lies. Not everybody is trying to show off their brains.
I agree that code should be as straightforward as possible, but I don't think books follow that rule.
Yes, you can have your pie and eat it :)
I’ve seen clever code that was 300% faster, half the lines, completely unreadable, and called once per session, for a total the time of 10ms in a workflow that was minutes long.
No amount of commenting could justify it.
There's nothing to say code can't be performant and legible. In fact I'm a bit confused what "clever" means here. Writing performant but illegible code does not take more cleverness than performant while legible.
Edit. Yes I get the difference and the reasons they do this. The wordplay crossover (cryptic, clever, etc) was notable to me, and reminded me of the link I posted above.