back
215 comments
Author here, thanks for posting.

Here's some more color on the reflection on comments, straight from the Linux Kernel documentation that capture my intention much better:

"Comments are good, but there is also a danger of over-commenting. NEVER try to explain HOW your code works in a comment: it’s much better to write the code so that the working is obvious, and it’s a waste of time to explain badly written code.

Generally, you want your comments to tell WHAT your code does, not HOW. Also, try to avoid putting comments inside a function body: if the function is so complex that you need to separately comment parts of it, you should probably go back to chapter 6 for a while. You can make small comments to note or warn about something particularly clever (or ugly), but try to avoid excess. Instead, put the comments at the head of the function, telling people what it does, and possibly WHY it does it."[0]

[0] https://www.kernel.org/doc/html/v4.10/process/coding-style.h...

> NEVER try to explain HOW your code works in a comment

Never is a strong word, sometimes the algorithm is just inherently complex and it's worth it to explain what you are doing.

Why is much more important, but it's also partially solved automatically by git blame and adding the task number to each commit message (and writing good commit messages which IMHO is more important than writing good comments). Each line of your code has commit message associated with it whether you care about it or not - make it useful.

Don’t agree. Longer pieces of code are way easier to reason about. Deep function nesting, which seems clean is very confusing mentally, and also difficult to describe in terms of function name.

Explain *why* you’re doing something a certain way. This also includes a little bit of how and what. Other than that, just make sure your business terms are reflected in the code, or at least have a proper definition of things, which you can easily reason about.

The WHY is also very useful in comments, especially in business/UI/glue code where special cases abound.
What's your take on the difference between explaining how code works and describing what it does?

I only ask because of bits like the TCP rate estimator sometimes have step by step comments that might be interpreted as explaining how the code is doing something.

For example take the app limited detection function: https://github.com/torvalds/linux/blob/master/net/ipv4/tcp_r...

The exception to the WHAT/HOW divide is working around a 3rd party bug. Documenting workarounds can help prevent reintroducing the same bug when someone edits or copies the code. This can be especially helpful if the 3rd party bug gets fixed in such a way that your workaround now fails.
> try to avoid putting comments inside a function body

This makes me sad. Think about others who will have to reverse engineer your code. Not every functionality should be split into a function, unless you want to add 10 layers of abstraction and misdirection.

I prefer over-commenting a lot, over under-commenting.

The only harm is, when you miss the important bits over too much blabla, or when you forget to update comments. There are not many worse things, than wrong documentation/comments.

"you want your comments to tell WHAT your code does, not HOW" but I agree very much to this.

I've seen this interpreted by smart engineers in a counter-productive way, in that they believe their code is so good that none of it ever needs any comments and hence they never write them despite the fact that their code isn't all that clear. It's more hubris than anything.

Otherwise, there are many techniques you can use to make the code self-explanatory. I've taken a comment before and restructured the code to literally read like the comment.

It’s an old assertion of the Refactoring community that a commented block in the middle of a function is a separate function trying to break free. If the code is interesting in its own right, move it.

That also extends to how. If the algorithm is interesting or complex enough you should move it as well, as the point of the host function is not to show how clever you are, but to accomplish a task.

Empirically I’ve found that I get much less pushback on algorithmic tweaks when I isolate them to a separate function. The reader doesn’t have to include them in their local reasoning, and I suspect but cannot prove that they tell themselves that they can always revert that code cleanly, so let’s just leave it be for now and see what happens.

I agree with almost all of these viewpoints. The comment one though isn't quite right.

Sometimes you just need a comment. For example, I was writing some code to an API and the company was offering a private experimental feature. The API was JSON, but this one feature was enabled by adding a small stringified JSON object to a field of the larger JSON post body. If a developer looks at it, they'll think "this must be wrong" but with a comment that briefly mentions why, everyone will be saved some time.

>Know when to break the rules. For rules like "don't repeat yourself," sometimes a little repetition is better than a bit of dependency.

Glad to see DRY called out here. I've seen so much crazy code simply to avoid breaking, The Rule.

> Syntactic sugar is usually bad.

I disagree with this one. It can be bad, but if it helps syntax get out of the way to reveal the intent of your code, I think it's pretty good

There's a really good book called "Code Complete" from 1993 (revised several times) that I think captures a lot of this sentiment in a more organized and illustrated way.

A lot of stuff on this list has been tribal knowledge for decades (well, except for the part about build pipelines, language choices, and Stack Overflow, etc.).

My first code mentors in the 80's & 90's said some of the same things in this list, and I passed them down to my mentees (?) as well.

https://www.powells.com/book/code-complete-9780735619678

This is a fine list, but not unlike many others. What I find missing are the deeper elements rather than the rules of thumb or general observations. Things that I find valuable after 10k+ hours are ways of transforming a conceptual understanding of a problem into abstractions that produce a comprehensible and maintainable implementation. Talking about naming variables in depth alone would be more valuable than this listing, and I do hope there will be follow-up posts that go in to some of these points as well as cover topics that don't neatly summarize as 1-liners.
Might disagree with the author on what is deliberate practice. I would say the implementing code at work is not deliberate practice in the sense that it’s defined in the original 10k hours thesis.

I think in the strictest sense deliberate practice is picking something that you’re weaker at, and spending time deliberately working on that.

I imagine that some part of the author’s 10k hours was working on projects outside their comfort zone, while others were within it. The argument would be doing stuff that you’re comfortable with or don’t have to think too hard about would not be deliberate practice.

Good list, and the litmus test is I would have disagreed with a lot of it when I started, or at least I'd have wondered why it mattered.

My summary, and it won't be useful at all, is that a lot of programming decisions come down to judgement. Comment or not? Config file or DSL? Is it ugly? Is is a rare feature of the language? All of these things are the kind of thing that you could argue if you wanted, but an experienced programmer will likely have better arguments.

One thing I still don't agree with is the first one. There's a lot of things, mostly trivial, that are easier to find on SO than in the source code. In fact something like "what's the idiomatic way to concat a string in $lang?" is best found on SO rather than the source code, because the source code will allow more than one way to do it.

For number 2 problems ("In many cases, what you're working on doesn't have an answer on the internet."), the answer is again judgement. For this you want to have a network of programmers you've built up over the years that you can ask. I have a couple of good friends on chat that I can just pop a question to, and it saves a heck of a lot of time. Hard to find though, they have to be someone who is basically gonna work for free for you, and you have to provide a similar level of service when they have a question for you.

>In many cases, what you're working on doesn't have an answer on the internet.

>That usually means the problem is hard or important, or both.

Really ? If a problem is important someone likely already tackled it. I mean 15 years ago this was less likely, but these days there's so much work in the open and search is very good, when I find there aren't any references for my problem it usually means I misinterpreted the problem or I'm doing something very niche.

After 30k/40k/??? hours of programming, I wish I had spent a chunk of the time learning how to play the piano well or something.
I will say, I think the one point in this article I disagree with is about finding answers on the internet. There are certainly been many times I've needed to dig into the source of something I'm working on, but much more often than not I've been able to find an exact (or close enough) answer with a couple of different Google searches.

Granted, this may be because the areas I work in are less technically complex than, say, writing low-level code or IoT instructions.

10,000 hours programming is not specific enough of a target to equate to Gladwell’s examples. It’s like saying “I practiced playing sports for 10,000 hours, so I am a professional athlete.”

Now, if you developed using a single language targeted on a specific platform for 10,000 hours while challenging yourself at a high level, you would have a very strong level of expertise in that area.

Furthermore, Gladwell made the distinction that the hours spent should be deliberate and tailored to improve skills. Working on tasks handed down to you by your superiors at Google is not deliberate practice.

Too many of the items are deeply influenced by Golang principles or quotes I have seen from Gophers. I think this is a very interesting Go-oriented reflections on 10k hours of programming.

I think it boils down to each 10k hours of programming on (or mostly on) a certain language will give your different reflections that we think are general.

"And the disciples came, and said unto him, Why speakest thou unto them in parables? He answered and said unto them, Because it is given unto you to know the mysteries of the kingdom of heaven, but to them it is not given. For whosoever hath, to him shall be given, and he shall have more abundance: but whosoever hath not, from him shall be taken away even that he hath. Therefore speak I to them in parables: because they seeing see not; and hearing they hear not, neither do they understand."
At least where I work, the DNS rule is "Batten's Law" because that guy's said it so many times, and been right so many times.

https://www.battenworks.com/

  It's DNS
  And, when you're sure it's not DNS, it's DNS
> Well, I'm certainly not a world-class expert

> Most recently, I worked as a professional software engineer at Google on Kubernetes

If this is not a world-class expert, who is?

Don't be afraid of simplicity: The most simple it is, the better it is
For me the most helpful general guideline has been. Make the code easy to change.

I can break rules like DRY, if the repeating myself makes it easy to change.

Configuration is hard. Most of the cases I see people eventually crank out their own DSL and "teach" other people to use it.
Reflections on 40k hours of programming. Developers are a pain in the ass. But I still love making things work!
> While rare, sometimes it's a problem with the compiler. Otherwise, it's always DNS.

I don't quite understand this one? Does it refer to domain name server? So if you're having network issues it's always DNS problems?

> Corollary: Most code out there is terrible. Sometimes it's easier to write a better version yourself.

I never cut-and-paste directly from stack overflow. I cut from several sources, combine the best practices and adapt everything to make something novel, and hopefully "better". But i think it's important that you understand what it does before you use it. This might seem self-evident, but my experience tells me not everyone agrees with this methodology. If i find inspiration to a solution, i usually leave a link to the original source or stack overflow page.

This is a great read. Posts like this make me not fear being “just a developer” for the rest of my life.
Good list, and indeed not really advice for beginners.

I'm not sure reading the standard library for language X is necessarily a good way to learn the conventions and practices of a language. Typically a standard library contains a lot of complex corner cases that don't need to be worried about when writing ordinary code.

(Expanding). The standard library authors don't know the users of the code. While when you're writing a piece of code with a limited number of developers (could even be thousands) you might, for example, say "all our accessors for class X return const results" while the standard library authors have to handle the non-const case"

> In many cases, what you're working on doesn't have an answer on the internet. That usually means the problem is hard or important, or both.

For me, it’s usually meant I’m doing something so wrongheaded it’s never come up before.

10K hours??! Try 100K hours (55 years x 50 wks/yr x 40 hrs/wk).

I still don't know much.

> 4. Syntactic sugar is usually bad.

I agree now, after switching from Python to Go.

> If it looks ugly, it is most likely a terrible mistake.

I agree with this, looking back at my first year of professional coding I just realise how important code review is. Even if you are working for a small software agency / consultant, you have to force them to do code review before merging. Otherwise, you will spend a long time trying to make your code look better which mostly you won't be able too because lack of experience

I recently reached 10k hours too this week. (I've coded more than 10k, but only tracked time for 10k) Here's my language usage for those 10k hours:

https://twitter.com/alanhamlett/status/1423738961550184449

I don't understand the 11'th one can someone explain to me also the given link seems broken.

> If you have to write a comment that isn't a docstring, it should probably be refactored. Every new line of comments increases this probability. (For a more nuanced take, the Linux Kernel Documentation)

I appreciate these, but in my experience it's not that relevant. The harder problems in programming are more of knowing your ecosystem. Knowing the design patterns necessary to create well meaning, understandable code in the first place. This is especially cumbersome when working on projects with complex data patterns.

For example, working with GUI applications and C/+ can make your code a big pile of garbage really quickly because representing your data in something like an ORM is not standard, you can't do the many tricks like getters/setters in C/+, but you can in Python, or C#, etc. The benefits of VM languages are, in my opinion, not appreciated enough.

In my opinion knowing the right tools for the job is far more important than how you comment your code, how you name your variables, or anything else. I wish there were more posts where people impliment an application with multiple tool sets and compare them, give insight into what some things are good for and not. "Tool Benchmarking" might be a good term for it.

> 23. While rare, sometimes it's a problem with the compiler. Otherwise, it's always DNS.

Is DNS here just referring to Domain Name System, as in to reference problems with systems out of our control?

Each point is true to me. Very nice job articulating these ideas.
> Syntactic sugar is usually bad.

When I read this, ES6 classes came to my mind :)

Great post btw!

Let me compare the ones I might've disagreed with as a newbie (out of college, maybe a few tens of hours total programming) and what I think of them now, after 17 years as a programmer.

- "Browsing the source is almost always faster than finding an answer on [the web, Stack Overflow didn't exist yet]." This would have taken a very long time as a newbie, not being familiar with C-style languages (I was working in PL/SQL and XForms, mostly) and the architecture of big software. Nowadays, depends how many levels of dynamic dispatch (the devil) the code uses. If it's more than one, the code is so unreadable as to be worthless to try to read.

- "Know the internals […].", same as above.

- "Syntactic sugar is usually bad." Depends how much more intuitive the sugar is than the salty version. Still the same opinion nowadays.

- "While rare, sometimes it's a problem with the compiler. Otherwise, it's always DNS." Disagree both as a newbie and now, but then I'm probably not working on anything similar to OP.

- "Some programmers are 10x more efficient than others." Certainly I was a <1x programmer as a newbie, but I don't think I've ever seen a 10x programmer. I've seen programmers which get features "done" by committing so many programming horrors that we were still dealing with the tech debt years later while they were at a FAANG, and I've also seen programmers which can whip up excellent code quickly but are unable to treat colleagues as adults.

- "There's no correlation between being a 10x programmer and a 10x employee (maybe a negative one)." I wouldn't have thought so as a newbie, but this rings true now. Visibility, agreeing with the boss on whatever they think is cool, being able to serve up banter on request, and joining all the "social" events are important because nobody is able to gauge programmer productivity yet.

- The "Heptagon of Configuration" is an interesting observation which I don't think I ever agreed with, but for different reasons. As a newbie because for most systems whatever we were using was usually decent enough, and now because I don't think this trend is cyclic but instead chaotic. We go from environment variables to Bash to INI to flags and so on. Usually this change is because we adopt some language or framework which staunchly refuses to treat anything but the Chosen Language as a valid configuration format, and so the existing configuration has to be adapted to work with N+1 opinionated (for the wrong reason) systems with as little pain as possible.

For me, the most valuable insight has been to understand the problem at hand with its intrinsic complexity, constraints and requirements. Only then can you construct efficient and clear abstractions with as little accidental complexity as possible.

Sometimes this can mean writing a very small amount of glue code calling external libraries. Sometimes it can mean avoiding a library/framework and rolling your own solution which solves a specific subset of the problem, enabling a smaller footprint and less dependencies. No silver bullet, really.

> If you have to write a comment that isn't a docstring, it should probably be refactored.

Yikes. Can't read past that.

There's lack of proof to back up the 10k hours. I get that he has worked 15 years at prestigious companies but I have to take his word on it. Some aphorisms jelled with me but other's didn't, so we're again at a "he said; she said" impasse.
How is reading a library’s source code FASTER than StackOverflow?
Sounds like the author is closer to 30,000 hours.
> 5. Simple is hard.

Yes.