Live data from Hacker News

Applying the Linus Torvalds “Good Taste” Coding Requirement

medium.com

291–300 of 302 posts

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

#291
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…

As a rookie programmer (but 10 years in IT, loving maths), this was my thought exactly. Basically a matter of field/domain definition, insofar as humans still have to interact with the code.

In short: most enterprise code should be elegant and simple, even if verbose (many conditionals, as little nesting as possible, etc) so that a 12 years old can understand it, because in real life you'll get much turnover and lack of means/skill/motivation. Hence, costly maintenance, etc.

Writing an open-source kernel consistently for 20+ years is an entirely different problem, and the fact that you use code in both these examples is a distant commonality of the problem sets; it is my experience thus contention that the human factor and real world conditions are paramount to ascribing qualitative assertions such as 'good' or 'tasty'. That is, until machines program themselves or others without human oversight. ;)

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

#292
post #113
post #98

Earlier quoted context omitted.

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.

Sure, but when programinng, what the machine does and how long it takes, sometimes does matter. I have to think of all those jQuery examples floating about out there that just do $('#foo') in several places -- sure, it looks simpler than putting it once into a variable, but from the viewpoint of what the computer ends up doing it's utterly ass-backwards.

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

#293
post #98

Earlier quoted context omitted.

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!

Actually, it's written exactly as often as the original construct.

The idea that writing more than 5 letters, or a for loop here and there, is this giant cesspool source of errors is totally alien to me. Of all the ways in which my programming sucks, this was never among them. So thanks for you permission, I'll use it wisely :P

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

#294
post #98

Earlier quoted context omitted.

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.

I disagree, I believe it is properly using abstractions to write simpler, more straight-forward code. I think of syntactic sugar as 1-to-1 replacements. For example, the -> in C and C++ is syntactic sugar for a dereference followed by a field access (ptr->field; (*ptr).field). If it's not a 1-to-1 replacement, then it's more likely to be an actual abstraction.

> I disagree, I believe it is properly using abstractions to write simpler, more straight-forward code.

Straightforward for some readers, or more straightforward for the CPU/GPU?

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

#295
post #292
post #113

Earlier quoted context omitted.

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.

Sure, but when programinng, what the machine does and how long it takes, sometimes does matter. I have to think of all those jQuery examples floating about out there that just do $('#foo') in several places -- sure, it looks simpler than putting it once into a variable, but from the viewpoint of what the computer ends up doing it's utterly ass-backwards.

There's no reason a `.where` should be slower than an explicit loop though. Indeed it should offer more opportunity for future performance improvements, because it doesn't constrain the implementation with irrelevant details - the compiler is free to e.g. make the loop run backwards, or split the collection into chunks and parallelize, if it figures that that would be faster.

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

#296

For the curious like me who wanted to see the assembly for the Linus examples and compare https://godbolt.org/g/sqdBrf . Most importantly they have the exact same number of branches and their loops are exactly the same size 4 instructions on all opt levels greater than 02. The setup code for the first one is much longer.

Here is also a somewhat representative example of various grid initialization pay attention to version 3 where the compiler unrolls the loop in O3 its likely the fastest version. https://godbolt.org/g/mMBhuW

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

#297

Earlier quoted context omitted.

The first version had a while loop and a condition. On the other hand, the optimized version only has a while loop.

I can see that. However, if I'm not mistaken, branches are costly only when they're mispredicted. Hence, the question (as I see it) is wether one can better predict the behavior of Linus' better version (which only has one conditional) or that presented above (where there's an early return condition followed by the while condition). It seems to me that the version above (which has two conditionals but is not like Lin…

Where is that early return you mention? I don't see the return keyword used in either examples. They both do the exact same while loop, but Linus' version adds a level of indirection to save a conditional later on. You're still touching the same memory in both cases so they should be identical in terms of cache misses.

From my understanding, the first version has two possible branch misprediction points while Linus' version only has one. This will probably only have a visible impact if the function is called in a loop however.

But to me the biggest advantage of the 2nd variant is its simplicity. This is the only way to stay sane with a growing codebase and keep shipping robust code.

Its no use getting a fast function if you can't integrate it optimally with the rest of the codebase. Raw performance isn't at the micro level but the macro one. This is where simplicity becomes critically important.

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

#298
post #274

I'm reminded of a quote from Moore in "Thinking Forth": "A lot of conditionals arise from fuzzy thinking about the problem. In servo-control theory, a lot of people think that the algorithm for the servo ought to be different when the distance is great than when it is close. Far away, you’re in slew mode; closer to the target you’re in decelerate mode; very close you’re in hunt mode. You have to test how far you are…

> That's part of a chapter of the book called Minimizing Control Structures. Since the book is creative commons and freely available, I decided to download the book and have a look. Figure 8.1, the "automatic teller" example is just downright hilarious. The author presents the code and throws a challenge at the reader: "Easy to read? Tell me under what condition the user’s card gets eaten." Here's the code: IF card i…

Just the raw formatting of that could be improved, by cuddling up ELSE IF from separate lines.

Aren't there some END tokens missing? Let me put them in:

  IF card is valid DO
    IF card owner is valid DO
      IF request withdrawal DO
        IF authorization code is valid DO
          query for amount
          IF request 
Okay, now:

  IF card is valid DO
    IF card owner is valid DO
      IF request withdrawal DO
        IF authorization code is valid DO
          query for amount
          IF request 
Okay, just one ELSE IF; not much opportunity for that.

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

#299
post #274

Earlier quoted context omitted.

> That's part of a chapter of the book called Minimizing Control Structures. Since the book is creative commons and freely available, I decided to download the book and have a look. Figure 8.1, the "automatic teller" example is just downright hilarious. The author presents the code and throws a challenge at the reader: "Easy to read? Tell me under what condition the user’s card gets eaten." Here's the code: IF card i…

Just the raw formatting of that could be improved, by cuddling up ELSE IF from separate lines. Aren't there some END tokens missing? Let me put them in: IF card is valid DO IF card owner is valid DO IF request withdrawal DO IF authorization code is valid DO query for amount IF request Okay, now: IF card is valid DO IF card owner is valid DO IF request withdrawal DO IF authorization code is valid DO query for amount I…

On that topic, I did a somewhat weird thing in C yesterday. I took code like this:

  for (;;) {
    /* original big loop */
  }
and turned it into this:

  if (compatibility_with_old_version) for(;;) {
    /* original big loop: same indentation level! */
  } else for (;;) {
    /* rewritten new loop */
  }
 
I.e.

  if (...) for (...) {

  } else for (...) {

  }
Works for me.

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

#300

Earlier quoted context omitted.

I can see that. However, if I'm not mistaken, branches are costly only when they're mispredicted. Hence, the question (as I see it) is wether one can better predict the behavior of Linus' better version (which only has one conditional) or that presented above (where there's an early return condition followed by the while condition). It seems to me that the version above (which has two conditionals but is not like Lin…

Where is that early return you mention? I don't see the return keyword used in either examples. They both do the exact same while loop, but Linus' version adds a level of indirection to save a conditional later on. You're still touching the same memory in both cases so they should be identical in terms of cache misses. From my understanding, the first version has two possible branch misprediction points while Linus'…

I was referring to the version in this thread's ancestor, which reads:

  remove_list_entry(entry)
  {
      if (head == entry) {
          head = head->next;
          return;
      }

      for (prev = head;  prev->next;  prev = prev->next) {
          if (prev->next == entry) {
              prev->next = prev->next->next;
              return;
          }
      }
  }
Post reply on HN