Live data from Hacker News

Applying the Linus Torvalds “Good Taste” Coding Requirement

medium.com

171–180 of 302 posts

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

#171
The example there about edges on an array is something I've had to directly deal with myself when I implemented a multidimensional image-processing function for GNU Octave. The problem is to find connected components in a binary image, where voxels are either 0 or 1. You want to find all the islands of ones, and you want to be flexible if diagonals count as being connected or not.

The problem, of course, is that along the edges you don't want to check for neighbours outside of the image boundary. I found no good way to do this for an n-dimensional image, after a few attempts of writing very complicated code. In the end, I ended up padding the whole image with a boundary of zeros, iterating over the padded image with an "if(current_voxel)" conditional that skipped checking for lit neighbours around the boundary, and when checking for lit neighbours at the original image's boundaries would give no neighbours at the padded zero boundaries.

The code was cleaner, but I incurred a big realloc, because N-dimensional images in Octave are stored as contiguous Fortran-order (column-major) arrays. I'm still looking for a better solution to this problem.

So, how do you do this cleanly?

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

#172

The root of the problem is that "the thing that points to an entity" is not a consistent concept in this kind list. Sometimes it's "head", sometimes it's an entity's ->next. I wonder what Linus would think of implementing the linked list with a dummy head node, having no value and pointing to the first entity. Personally, I think that would be tasteful. It allows for simple loops like the "good taste" one, but you do…

This is exactly what Linus's code does. "indirect" is just "dummy->next" but doesn't pay the extra space cost for the node value.

If writing this code in a higher level language, I think the dummy node would be more appropriate and idiomatic despite the slight increase in space.

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

#173

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. Th…

I agree partially w.r.t. testability of branchless code, but there's a flipside too: often the root cause of an edge case is in data-structure shape, so full coverage isn't necessarily sufficient. In other words, if an edge case is "folded into" the normal path via something like Linus' trick, you still need to actually test the case where (in this example) `head` is being removed, or else you aren't certain that the folding of cases is valid. And if you're testing that case, then you'll have full coverage of the original (branchy) code too.

Totally agree w.r.t. performance, though. Even if the branch is never taken, control flow can reduce the scope of other compiler optimizations.

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

#174

The root of the problem is that "the thing that points to an entity" is not a consistent concept in this kind list. Sometimes it's "head", sometimes it's an entity's ->next. I wonder what Linus would think of implementing the linked list with a dummy head node, having no value and pointing to the first entity. Personally, I think that would be tasteful. It allows for simple loops like the "good taste" one, but you do…

It's one more pointer that you have to resolve, everytime you do something with the list. Sounds smelly to me.

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

#175

Not being used to C syntax, I took this as a typo at first: indirect = &(*indirect)->next; The position of the parentheses make it look like you're dereferencing only (* indirect). But on second look, you need the parens there so that it's (* indirect)->next as opposed to indirect->next. Then the & operates on the whole thing. I'd be tempted to wrap it in a second set of parens for clarity, but perhaps it's entirely…

Personally, I've never been able to memorize the precedence ordering of *, &, ., and ->, so I always use those extra parenthesis on non-trivial lines.

But if it goes naturally for somebody, more power for them. It'll just take me a few more seconds reading a few lines.

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

#176
post #155

Earlier quoted context omitted.

But now you're making argument about performance, not "good taste". Often, performant code is not very tasty.

Are you seriously arguing that Linus would think cleanly performant code is not in good taste? You're welcome to ask him that directly and see what he says. EDIT: Okay, I'm being excessively snarky there; my apologies. I will say instead that is that "good taste" depends on the context. What's "good taste" for kernel development isn't necessarily the same as "good taste" for enterprise development or the same as "goo…

Haha, getting bullied does not sound very delicious to me.

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

#177

Earlier quoted context omitted.

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. Th…

I agree partially w.r.t. testability of branchless code, but there's a flipside too: often the root cause of an edge case is in data-structure shape, so full coverage isn't necessarily sufficient. In other words, if an edge case is "folded into" the normal path via something like Linus' trick, you still need to actually test the case where (in this example) `head` is being removed, or else you aren't certain that the…

Yes, this is a good point. I had thought of this too and somehow convinced myself that the "head" case disappeared (since the non-"head" case would fail if "indirect" weren't initialized properly), but I'll admit that's a shaky argument.

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

#178
post #155

Earlier quoted context omitted.

But now you're making argument about performance, not "good taste". Often, performant code is not very tasty.

Taste is malleable and relative. One can even entertain different notions of taste. I personally have at least two – "understandable" and "performant" – and they aren't always (but sometimes are) exclusive of each other. I suspect Linus's "taste", given Linux's problem domain, tuned to some combination of performant + testable + reviewable + portable. In the example given, Linus's rewrite meets these requirements; he…

I feel at this point, the notion of 'good taste' has become even more ill-defined, something very personal. Then the notion is not very useful as a coding guideline.

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

#179

I've been told many times that it's better to eliminate edge cases. I still don't really believe it as a universal law. When explaining the algorithm "remove an element from a linked list" to someone else, I would say "starting at the head, go along the list until you find the element; then delete the element". When explaining the algorithm "delete an element from a linked list", I would say "if you're at the head, u…

> I still don't really believe it as a universal law.

If you were doing kernel development, you would. If you were writing enterprise CRUD applications, you wouldn't even think about it, and if you were developing hight throughput middleware, you'd switch that law on and off depending on where you are on the code.

Or, at least, s/would/should/.

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

#180

For my money, Linus's example of "good taste" gives up rather a lot of clarity to achieve succinctness. The original is simple and clear. His preferred version is shorter, but also harder to understand because of its use of a complicated indirection. And that's not good taste. It's just showing off. “Programs must be written for people to read, and only incidentally for machines to execute.” ― Harold Abelson, Structu…

Do you do much C programming?

If I put my "Java goggles" on, the first, "untasty" snippet looks so very obviously to be the right way to do it. But...

If I put my "C goggles" on, the "clever" version from Linus looks much more direct, obvious, and better in general...much like the final example from the article author.

Post reply on HN