Live data from Hacker News

Applying the Linus Torvalds “Good Taste” Coding Requirement

medium.com

111–120 of 302 posts

Re: Applying the Linus Torvalds “Good Taste” Coding Requirement

#111
post #98
post #2

I was given a piece of advice very early on in my career that I've always been grateful for, which is fundamentally the same as this. IF and FOR are both code smells. One case of this is just simplifying loops with some functional goodness var listOfGoodFoos = new List (); for(var i = 0; i VS return listOfAllFoos.Where(x => x.IsGood); But perhaps a more interesting point is it can also be a a sign of DRY gone wrong -…

It's not simplifying it though, it's just hiding the complexity in syntactic sugar. I prefer the first way of doing things vastly over the second. Yeah, it's more code, but it's also more or less "what is actually happening", instead of an euphemism which has to be unpacked.

At some point that breaks down though doesn't it. I mean from one perspective a conditional in high level code doesn't describe "what is actually happening, either." That's especially true if an optimizing compiler or interpreter mangled it up.

From another perspective your argument can be applied to any function call in library code.

In either case I don't think your position is that strong.

Re: Applying the Linus Torvalds “Good Taste” Coding Requirement

#112
post #101
post #2

I was given a piece of advice very early on in my career that I've always been grateful for, which is fundamentally the same as this. IF and FOR are both code smells. One case of this is just simplifying loops with some functional goodness var listOfGoodFoos = new List (); for(var i = 0; i VS return listOfAllFoos.Where(x => x.IsGood); But perhaps a more interesting point is it can also be a a sign of DRY gone wrong -…

Well the second snippet hides the loop and conditional which surely are implemented in "Where". Is that a code smell by proxy?

Depends which expresses the actual intent more clearly. To my mind, that it's the list of foos that are good is what's important, and the loop and conditional are implementation details.

Re: Applying the Linus Torvalds “Good Taste” Coding Requirement

#113
post #98
post #2

I was given a piece of advice very early on in my career that I've always been grateful for, which is fundamentally the same as this. IF and FOR are both code smells. One case of this is just simplifying loops with some functional goodness var listOfGoodFoos = new List (); for(var i = 0; i VS return listOfAllFoos.Where(x => x.IsGood); But perhaps a more interesting point is it can also be a a sign of DRY gone wrong -…

It's not simplifying it though, it's just hiding the complexity in syntactic sugar. I prefer the first way of doing things vastly over the second. Yeah, it's more code, but it's also more or less "what is actually happening", instead of an euphemism which has to be unpacked.

All programming languages are "euphemisms" in that sense - even C has a lot of layers between it and how modern hardware behaves. It is simplifying if it expresses the important aspects of the result rather than the implementation details of how the machine calculates it.

Re: Applying the Linus Torvalds “Good Taste” Coding Requirement

#114
Here's even more "tastier" 2 lines version:

  remove_list_entry(entry)
  {
      for (indirect = &head; (*indirect) != entry; indirect = &(*indirect)->next);
      *indirect = entry->next;
  }
The big problem: both Linus's and above versions don't handle the case if entry wasn't found, for example, if entry was null. This is the fundamental issue with trying make code overly compact: sometime you lose the sight of important edge cases. Segfaults are not tasty. I generally prefer to write code that reflects my thought process and avoid unnecessarily try making it compact. As Knuth had said "Programs are meant to be read by humans and only incidentally for computers to execute”. Uglier versions allows to explicitly documents edge cases. This enables future maintainer to make sure these cases are covered when s/he makes code changes. Obviously taking this to another extreme would ruin this. The better taste lies somewhere between the compact Linus's version and some zeolite's too verbose version.

Small problem: Another thing to think about is extra pointer redirection required in Linus's code. This is fine for most cases but if I was dealing with very large list over and over then that's unnecessary perf hit.

Re: Applying the Linus Torvalds “Good Taste” Coding Requirement

#115
post #98
post #2

I was given a piece of advice very early on in my career that I've always been grateful for, which is fundamentally the same as this. IF and FOR are both code smells. One case of this is just simplifying loops with some functional goodness var listOfGoodFoos = new List (); for(var i = 0; i VS return listOfAllFoos.Where(x => x.IsGood); But perhaps a more interesting point is it can also be a a sign of DRY gone wrong -…

It's not simplifying it though, it's just hiding the complexity in syntactic sugar. I prefer the first way of doing things vastly over the second. Yeah, it's more code, but it's also more or less "what is actually happening", instead of an euphemism which has to be unpacked.

> it's just hiding the complexity in syntactic sugar.

And that complexity is only written once, instead of multiple times for a single project

You can have as many FOR and IF branches that you want, but only if they are all bugless!

Re: Applying the Linus Torvalds “Good Taste” Coding Requirement

#116

I dunno, the first example seems unsatisfying. The original has that ugly condition, the "good" version seems overly clever. And for all the talk of taste and aesthetics, both versions ignore an elephant in the room: defensively dealing with `entry` being absent from the list. Not that I've never abused addresses like this. But having written this multiple times, I currently prefer something like this: remove_list_en…

Independently of style, taste, BigCo, edge cases, assumptions and other considerations, I still find a major regression in your version:

Instead of one variable allocation and one test in the loop, your version has one allocation and TWO tests.

Adding weight in loops has a major performance impact.

Re: Applying the Linus Torvalds “Good Taste” Coding Requirement

#117

These are great examples, and they hint to, but do not mention, the big counterpoint: development time. In his own examples, the author admitted that though the code was ugly, it worked. He then spent extra time reworking the existing code to make it, well, prettier. "If I had more time, I would have written a shorter letter." -- Voltaire The problem is that, in many (most?) professional settings, the developer is un…

"If I had more time, I would have written a shorter letter." -- Voltaire

You're quoting Pascal, not Voltaire ;)

Re: Applying the Linus Torvalds “Good Taste” Coding Requirement

#118

I dunno, the first example seems unsatisfying. The original has that ugly condition, the "good" version seems overly clever. And for all the talk of taste and aesthetics, both versions ignore an elephant in the room: defensively dealing with `entry` being absent from the list. Not that I've never abused addresses like this. But having written this multiple times, I currently prefer something like this: remove_list_en…

I don't think anyone's mentioned that there are two functional benefits to Linus's version: testability and performance.

The author touched on testability. Dropping the "if" case eliminates one code path that may contain bugs.

But also, the revised code may perform a lot better if you're searching a lot of short lists. In that case, the target item has a large, though not likely, chance of being first in the list. This kills predictability of that "if" branch. Eliminating it can save ten cycles or so, possibly shaving 25% or so off the runtime of this function for short lists. (For large lists, the branch becomes predictable, and you start having cache issues due to the list's linked nature.)

My current side-project is an NES emulator. Nearly all my (non-algorithmic) performance enhancements have been of this nature: find some unpredictable branch nested inside a tight loop → eliminate the branch with "clever" logic → 25% performance gain on that loop.

(That there are no checks for "error" cases is a distraction. There aren't any in the original example either, because it's an example and the error cases aren't relevant to Linus's point.)

Re: Applying the Linus Torvalds “Good Taste” Coding Requirement

#119
post #90

> it only performed 256 loop iterations, one for each point along the edge alarm bells There are only 252 points along the edge. This code will act on each corner twice. If you were performing an operation like `+= 1` on each edge element, this code would be wrong. When you copy and paste it later and change all the `= 0` to something else, you might end up with an unfortunate surprise. Once I saw this mistake in the…

Here's my fix: for (i = 0; i This way, for every row/column, the loop acts on all but the last cell, which is actually the first cell of some other column/row.

I feel like for the each side you could actually handle two items per iteration, one forwards _and_ one backwards. That way your iteration count could be halved.

Re: Applying the Linus Torvalds “Good Taste” Coding Requirement

#120

Earlier quoted context omitted.

Screw 'taste', go for obvious . If you're at BigCo and your codes going to be maintained by disinterested drones/ random contractors/etc, obvious code is better. And lack of checking on entry pissed me off too.

>If you're at BigCo and your codes going to be maintained by disinterested drones/ random contractors/etc, obvious code is better. But what if you're Linus Torvalds and maintaining the Linux kernel ?

Obvious is still important. Even kernel developers make mistakes.

The 'good taste' example may be more concise but how likely are you to spot bugs in it?

Post reply on HN