← Back to context

Comment by khaledh

5 years ago

My favorite quote about this topic:

   Measuring programming progress by lines of code is like measuring aircraft building progress by weight.  - Bill Gates

My personal point of view is that: every line of code you write is a liability. Code is not an asset; a solved problem is.

Edit: To clarify, I'm definitely not encouraging writing "clever" short code. Always strive to write clear code. You write it once, but it will be read (and potentially changed) many, many times.

"My point today is that, if we wish to count lines of code, we should not regard them as “lines produced” but as “lines spent”: the current conventional wisdom is so foolish as to book that count on the wrong side of the ledger." -E. Dijkstra

  • I prefer the Gates version. Dijkstra's implicit premise rather naively assumes that it is somehow less expensive to produce fewer lines of code. It's arguably such an absolute statement that it subtly encourages people to engage in undesirable behaviors such as playing code golf at work.

    Gates's, on the other hand, accurately captures the reality: while, all else being equal, a lighter-weight design is preferable to a heavier one, it takes some skill and effort to actually produce the lighter design. Which leaves open the possibility that doing so may not actually be worth the effort.

  • The relevant metric isn't lines but concepts: Which code does it in the fewest new ideas? Generally, that's the best, where "new ideas" would be ideas new to a domain expert. For example, in a video game, each of the specific monster types is an idea someone who is an expert in that game would know. The ideas in the memory management code are new. You can't remove all code relevant to a specific monster without removing that monster, at which point you're no longer implementing the same game, but slimming down the number of new concepts in the memory management code is not directly relevant to gameplay.

    In short: Make program logic similar to business logic.

  • I'd expect nothing less wise from Dijkstra. I feel like every week I learn something new from that man.

I agree. But, like everything, even this concept gets abused.

Example: "Zero code solutions". Hell, we even had that back in the old days with Java frameworks doing a ton of configuration via XML files. Sure, it's not "code", but it's basically the same thing and still a liability. Especially if there's a very steep learning curve to all of the features/configurations that you'll never use.

A more subtle problem with abusing this idea is the over-dependency on third party code. Sure, it might look like you haven't written any code when you do `npm install foo`, but really, you've just placed a bunch of trust in some other person. Do you vet your dependencies' authors the same way you vet potential employees at your company?

There's a fine line and it's an art form figuring out when to bring in outside code or to NIH it. IMO, of course.

  • I'm hitting this right now with having just inherited maintenance of a complicated CI pipeline with a lot of intermediate containers based on generated Dockerfiles, all of which runs by bind-mounting docker.sock— basically stuff that might have been best practice 3-4 years ago, but for which there are absolutely better solutions now.

    Anyway, it's interesting evaluating those potential solutions, because certain things like going to a daemonless, rootless, bind-less build based on podman/buildah is a no-brainer, but the next frontier beyond that has a bunch of tools like ocibuilder, cekit, ansible-bender, etc which want to establish various ways of declaratively expressing an image definition, and although the intent is good there, it's absolutely not worth getting sucked into long-term dependence on pre-1.0 tools with single-digit number of contributors and an uncertain maintenance future.

Some take "line of code" literally. Others see it as a stand-in for complexity. Because one can certainly make a short program that's far more of a liability than a long one.

I'm wondering if there's a quality term for a "unit of complexity" in code? Like when a single line has 4 or 5 "ideas" in it.

I think it's in the application for DE Shaw that you're asked to number the lines of code you've written in your career in the various languages you claim to have experience in.

To be more precise, every line of code is debt. You get immediate benefits (working software) but you need to pay recurring obligations (bugs).

Just like debt, there is a right amount to have: too much and you are incapacitated because you owe more than you can produce, too little and you don't have enough runway to produce what you want. Note that I'm talking about from a company's point of view.

Agree. But then the problem becomes how to count solved problems. One equally terrible practice is to count number of tickets solved. I found this is somewhat true in my career: bug fixes == job security. I cannot morally accept this but I have seen this again and again.

This is great. Another thing is that sometimes leaving things as-is can be better than making changes.

The problem you might be avoiding is change.

Things that are bad should probably be fixed, though.

> My personal point of view is that: every line of code you write is a liability.

Very true... but also false in a way.

Here's a little bit of functionality that has to be in there to implement the way we're solving the problem. That code is a liability; it would be better to solve the problem in a way where we don't need this bit of code.

But given that we're solving it this way, let's say that this little bit of functionality may be implemented in one line, which is almost unreadable, or in five very clear lines. That one line is far more of a liability than the five lines are.