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…
Another issue both versions have is that they will not tolerate head being NULL. Don't be afraid of double pointers, although they may seem overly clever at first glance, they can be really helpful for situations like this. Linus's code is considerably shorter, and not particularly difficult to debug or to understand, assuming you understand double pointers. Another case where double pointers can be really useful is…
Applying the Linus Torvalds “Good Taste” Coding Requirement
121–130 of 302 posts
Re: Applying the Linus Torvalds “Good Taste” Coding Requirement
#122I 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 -…
Another piece of context in a business app might be - "Do we need these values now or later?" That is, should this be lazy, stream results, something like that? I am assuming this is supposed to be C#, but still speaking somewhat generally. You might need to instead yield rather than looping and returning an intermediate list. Better yet, I'd also look for you to return something like a read-only list (ex: IEnuemrable in C#) since this is a query result and that can be done with the first version.
Unfortunately if we had been writing a game though lets say, I would have failed you miserably for the latter version and added 1 mental strike to the "send you packing" count. Why? For loops are most certainly not code smells on most platforms. As a few people said, the mechanics of "Where" in some languages may just be cloaking a for loop. More importantly, for loops tend to be much more performant, can be inlined easier, and generally produce less garbage than lambdas and other similar language constructs. It may different than I last looked, but back when I used to touch C#, for was most certainly preferable for anything performance sensitive provided you didn't need laziness, and if you did, there's still at least "yield" (though at that point, we're approaching what Where can does anyway). I could go on about cache lines, trashing, GC pauses, and so on, but hopefully you get the idea.
Overall, I am afraid I must disagree and point out that your advice you treasure is too generic. FOR and IF are very valuable in certain contexts. I think the real advice someone might have been trying to give you is to aim for more functional constructs, that is functions that are pure/idempotent/referentially transparent, compose, and operate on sets of data where possible rather than individual points of data. Like any advice, this isn't universal and quickly unravels in many situations such as performance-sensitive contexts like game programming, real-time programming, and so on, or may in fact just be the best practice of the target language.
Re: Applying the Linus Torvalds “Good Taste” Coding Requirement
#123I don't know how to reconcile Linus's track record is of indisputable brilliance and success (I use Linux and Git on a daily basis and am eternally grateful for both), with the fact that I would absolutely DESPISE working with a peer with the kinds of attitudes and opinions on coding that Linus has. I think the problem I have is that a lot of people use Linus's examples and stories as justification for their own subo…
The rest is free to work with another maintainer if they wish to...
But yeah, don't try to mimic him on people skills. I don't think he ever said it was a good idea to do so...
Re: Applying the Linus Torvalds “Good Taste” Coding Requirement
#124Re: Applying the Linus Torvalds “Good Taste” Coding Requirement
#125I'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…
Most programming languages try their best to make things easier than easy, in order to maximize programmers' productivity. The focus on this parameter alone over-promotes the "worse is better" or "good enough" mindset.
That doesn't fare well with kernel programming. It's even worse with Forth. As soon as your "word" (function in Forth lingo) has to deal with more than two or three variables, you're in trouble. As soon as you have more than two levels of control-flow structures, nightmares begin.
If you're looking for programming practice then I recommend Forth. It may or may not be a "practical" language for you, but it makes you really think about complexity.
Re: Applying the Linus Torvalds “Good Taste” Coding Requirement
#126I 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…
assert (head && entry)
up there.Re: Applying the Linus Torvalds “Good Taste” Coding Requirement
#127Earlier quoted context omitted.
To me, its 'clever' code.... i.e. it should be simplified. This is not good code, it requires too much thought to realise what its doing.
It's busier to look at due to the syntax of the language, but if you're comfortable with pointers one could argue that it's conceptually simpler than the first example. And since linked lists are all about pointers, operating on the pointer directly seems logical. That said, for someone unused to the syntax (as I am!), I agree that it is definitely harder to mentally parse. So which is objectively better probably dep…
I guess when your audience is kernel developers, this isn't that much of a problem...
Re: Applying the Linus Torvalds “Good Taste” Coding Requirement
#128Re: Applying the Linus Torvalds “Good Taste” Coding Requirement
#129Here'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…
Re: Applying the Linus Torvalds “Good Taste” Coding Requirement
#130I don't know why I'm even replying, this will get so much hate here, oh well... 1. Just because things aren't done "the way you would do them" doesn't mean they're "bad" or "wrong". 2. If you're not on a solo project, I've found writing correct but less "clever" code to help shorten ramp-up time for new devs and be more beneficial to future maintainability of the code-base and system. TL;DR; Swapping values by XOR'in…
Absolutely. Further, I would consider Linus's one-liner 'indirect=...' to be 'clever' code. If I were reviewing it, I would want it expanded into more obvious code as it requires too much cognitive overhead to parse.
I don't find the pointer syntax that difficult to reason with.
How would you expand the code?