Live data from Hacker News

Applying the Linus Torvalds “Good Taste” Coding Requirement

medium.com

281–290 of 302 posts

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

#281
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 as taste is a subjective thing as is often hard to articulate... I think my biggest complaint about that code is that I had to read all of it to make sure there weren't other cases where the card gets eaten. And try to follow what was going on.

Taste-wise, an easy fix for this is to do early exits. Instead of nesting, you could easily do (I'm on mobile so no fancy formatting):

If card is not valid: return message

If user is not valid: eat card; return

Etc

Now that's my personal taste. It makes it way simpler to quickly skim and understand what's going on.

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

#282

Earlier quoted context omitted.

I'm not a low level programmer, so this is a honest question. In the better version, why doesn't the while condition (that must be tested at least once) present predictability problems whereas the if check in parent does?

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 Linus' worse version because it has an early return) should be similarly costly to predict. Consider the situations where either most of the calls are to remove the first element (A) or most of the calls aren't (B). Let's see what happens in these cases:

- On Linus' code, the while is evaluated the first time. In case A, the while is correctly predicted to exit the while, the swap is made and the function ends. In case B, where the while yields true many times before hitting our element, you should have to pay the cost of a misprediction when you finally find it.

- In the early return code above, the situation is... the same. In case A the early return if is predicted correctly to yield true, and the function ends. In case B, the early return if is correctly predicted to yield false and then the while predicts mostly trues until you finally hit your element, time at which you pay the same misprediction penalty than above.

So... aren't both functions similarly expensive in terms of branch misprediction costs? Am I fundamentally wrong on my understanding on this issue?

Thanks for the explanation!

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

#283
post #34

Speaking of coding niceties, when I started branching out from bash into a 'real' language, Python, I couldn't find a switch statement. A colleague of mine said that Python didn't have one, and that switch statements were a 'code smell'. I didn't really understand that, and asked about those times that you genuinely could use a switch statement, and the answer was "just use a long if-else function". I can't remember…

There are multiple alternatives to switch (or if) statements and I would generally agree switch statements are mostly a code smell. As one posters described, using the fall-through behavior is more what justifies it and the real difference. I know you asked for ELI5, but let me give you some options to think about how you code on a broader level and how to eliminate both if and switch or at least improve them. If you…

Thanks for the write-up. I've had to re-read a couple of bits, but that's how you learn :)

My switch use to date has almost entirely been about parsing commandline args - one of the two time I didn't do that was when my colleague talked about the code smell.

It's been interesting watching how new areas in programming just unfold potential in front of you as you learn. My bash scripts used to be relatively simple, serial things, then a mentor forced me to start using functions - and that was eye-opening. Things made more sense, and not least because I had to keep less 'state' in my head. You mention map and similar, and this is something I haven't really touched yet, but it sounds like it'll help some of the things I do (mostly ops scripts).

Thanks again for the write-up.

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

#284
post #261

Earlier quoted context omitted.

Pascal has references and pointers too so why would they not be able to do it in a very similar way?

In the original pascal pointers/refs came only out of new (AFAIR), you couldn't point into structures or to local variables. That makes this trick impossible. 'Modern' 'pascals' were different.

I'll grant that you can't do it quite as efficiently as in C but you can do the same trick as I showed for VB.Net (in another post in this thread) and create a new entry that points at the head then use that as your indirect pointer. The problem is caused not by being unable to point at locals or members but by Pascal's pointers being strongly typed so that you can't simply dereference some random word length memory cell to get a new reference.

So not identical but still simpler than the tasteless version.

I thought that this was such a fundamental idea that it should be on Rosetta Code but the page for it at http://rosettacode.org/wiki/Singly-linked_list/Element_remov... is empty.

Perhaps we should all rush over there and fill it in. :-)

Edit: See entry on RC at http://rosettacode.org/wiki/Singly-linked_list/Element_remov...

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

#285

Often I find myself solving problems in a single performant SQL with lateral/cross joins before hitting the business logic code in order to simplify the logic part into a single loop with no conditionals/edge cases. Turns out this is not the best practice because you will have to explain all about your clever use of olap functions and lateral joins to someone less knowledgeable who has to append to your code.

I would argue that having developers that don't understand and won't bother to learn SQL working on application dependent on SQL-based DBs is the not-best-practice there, not proper and efficient use of SQL by developers who do know what they are doing.

You are right, of course, but they have "working knowledge" of sql which is adequate for most reports and operations.

Just not the "high level" SQL someone armed with the knowledge of functional programming could conjure when faced with the alternative of writing lots of nested conditional statements and loops in an imperative language because it would bore him to pieces.

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

#286
post #264

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…

> It's so naturally a two-case problem that I'd be really surprised if anyone came up with the one-case answer first. [Raises hand] I always did it Linus' way in C (way before him); I don't remember if I ever had the need in assembly before.

Fair enough. I stand surprised! How would you describe the algorithm to a friend, then?

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

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

> Yes, it's easy. It gets eaten if the owner is not valid. Took one glance.

Nit-pick, but it seems that the card only gets eaten if the card is valid AND the owner is not valid. If the card isn't valid, the owner is never checked and the card isn't eaten.

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

#288
post #283

Earlier quoted context omitted.

There are multiple alternatives to switch (or if) statements and I would generally agree switch statements are mostly a code smell. As one posters described, using the fall-through behavior is more what justifies it and the real difference. I know you asked for ELI5, but let me give you some options to think about how you code on a broader level and how to eliminate both if and switch or at least improve them. If you…

Thanks for the write-up. I've had to re-read a couple of bits, but that's how you learn :) My switch use to date has almost entirely been about parsing commandline args - one of the two time I didn't do that was when my colleague talked about the code smell. It's been interesting watching how new areas in programming just unfold potential in front of you as you learn. My bash scripts used to be relatively simple, ser…

It sounds to me like you also need to start focusing on atomic functions and abstractions more in general. Your functions should do one things as I mentioned.

Regarding "map," "reduce" is probably the one you want to learn first because you can express many functional constructs like "map" in terms of "reduce."

As a general word, parsing command lines almost always tends to be ugly. My general advice here would be to use the built-in stuff or at least a well-used library as much as possible. If you are finding that you are doing a lot of work yourself or using reg-exs that you made, that's often a side that you are doing something wrong.

Anyway, lots more but I don't want to overwhelm. Good luck!

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

#289
post #280

Earlier quoted context omitted.

Like most things, it's all contextual. Were I your manager and we were working on a business app, this might pass code review just fine or I might even suggest what you did here if you had showed me the original. 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 s…

I absolutely agree with you about performance stuff, if you are in a position where milliseconds matter this may well not be the right way of doing things. Also, to open up another interesting area, Linq operating on IQueryable objects can do some pretty interesting stuff in the background, merging sql queries and the like. I've never looked into if it does anything similar for IEnumerable - although I will should th…

Things like FOREACH are good sane defaults, so the justification only happens based on what you are doing like in the performance example.

IQueryable actually is a superset of IEnumerable (implements it - https://msdn.microsoft.com/en-us/library/system.linq.iquerya...). It is generally useful if you want the laziness and ORM/ORM-like features. If you are using LINQ with SQL, then it would be better to return something like that for many use-cases. IEnumerable is good for general use of course and when you want to make the assumption that you "don't need" all that stuff which is pretty good one for more general cases where you just want read-only results or lazy read-only results (via things like yield).

I agree about potential. Nested FOR and IFs though raises that potential hugely. There is rarely a reason to be nesting more than a few levels deep. In many decades of programming, of course I have deeply nested, yet I have refactored it each time. I have managed to avoid doing excessive nesting the entire time as have most of my colleagues. I am sure someone can find a piece of code somewhere written for something that simply cannot be refactored well or justifies itself otherwise, but I'm not afraid to say statistically that is easy to avoid and hard to justify. I think the nesting issue just raises a bunch of flags including: performance, composability, reusability, clarity, maintenance, and cloaking. So in that sense I do feel it is what you describe as an anti-pattern more than a code smell.

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

#290

Earlier quoted context omitted.

>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?

> how likely are you to spot bugs in it?

Depends on what you methods are.

Post reply on HN