Live data from Hacker News

Avoid Indirection in Code

matthewrocklin.com

61–70 of 220 posts

Re: Avoid Indirection in Code

#61
While the example in the article isn't great for making the point I actually agree with the main idea.

I understand the arguments for 'Uncle Bobifying' code but I think, as the article says, there's a balance to be struck. It's highly likely the next time I see your code (or my code if I'm coming back to it a month or two later) is when I need to fix a problem with it. While it's useful to have it split up into logically discrete chunks with sensible naming these 2-4 line functions far increase the mental load of the code.

Given I'm debugging the code because there is presumably a problem with it I can't trust these sensibly named functions to do what they say, I need to check their internals to reason about changes in application state. Though well named functions at least help the maintenance programmer reason about the why they're equally liable to code rot as the comments they replace.

As in all things there's a balance to be struck but I'd rather see a 20-30 line method than jump between 5 files because someone has read Clean Code recently.

Re: Avoid Indirection in Code

#62
post #40

It's not indirection , it's bad abstraction that's the real issue here. Consider the example used in the article: if x.startswith("foo"): do_something_with(x) if is_foolike(x): do_something_with(x) The problem with both of these variations is that the "if-statement" doesn't have any meaning behind it. There's no gain in the indirection presented here. Whereas the following code has meaning: if checkHasPermissions(x):…

Actually, it would be a perfectly fine mini-encapsulation as-is. If you need to know whether something is foo-like or not, it's far better to have that test in one place rather than repeated all over the codebase. Otherwise debugging or modification would be a nightmare.

Even from a code U/X perspective this is better. How is someone going to know that x.starts_with("foo") means that the object is foo-like, rather than some subset comparison only? The name "is_foolike()" tells them unambiguously what information the function will return and more importantly, what the information means. Abstraction is about assigning higher order meanings to groups of information and behaviors so that we humans can keep the concepts straight in our minds, and is_foolike(x) is a lot easier to understand the underlying meaning of than x.starts_with("foo").

How you react to something being foo-like or not is a question for a higher abstraction level to decide, and present a unified front from there, like get_foolike_items(y), which in turn is needed by get_high_value_targets("sweden") (because all high value targets have foo-like metadata), which is in turn passed to launch_nuclear_missiles(targets).

Re: Avoid Indirection in Code

#63
I agree with OP, if a function just returns the result of another function without any additional processing then it usually means that one (or both) function's name does not accurately describe what it does.

The name of a function should abstract away from "how it does something" not "what it does".

Re: Avoid Indirection in Code

#65
post #56

The point made by the article (avoid using due to problems for debugging and code review etc.) does not hold much water. 'Indirection' can be invaluable while separating 'how you got it' from 'what to do with it' (it=some data), for example. 'what you do with it' can remain unaffected by changing 'how you got it'. This will not mess with code review practices but make understanding the pieces easier. It will also mak…

While delegation involved indirection, indirection does not necessarily mean delegation.

As other people have voiced, there are concerns about following the plot.

I think it’s a bit like writing. I can paint a clear picture in your head or I can torture you slowly while relating the same four basic facts. While I have achieved the task in both you may not wish to work with me long if I only ever achieve the latter.

Re: Avoid Indirection in Code

#66
post #58
post #56

The point made by the article (avoid using due to problems for debugging and code review etc.) does not hold much water. 'Indirection' can be invaluable while separating 'how you got it' from 'what to do with it' (it=some data), for example. 'what you do with it' can remain unaffected by changing 'how you got it'. This will not mess with code review practices but make understanding the pieces easier. It will also mak…

Yup, seems like the author had trouble following badly written abstraction and/or indirection and came up with the idea that they are bad. Abstractions are invaluable if you are dealing with a large codebase. Even the original author can’t keep everything in their head. Indirections are invaluable if you want to be able to modify code in the future without making a gigantic mess — and potentially breaking compatibili…

Did you know you can die from drinking too much water?

Take care pursuing things for their own sake and not for a reason (I suspect you do but impressionable people are reading along with us).

Re: Avoid Indirection in Code

#67

While the example in the article isn't great for making the point I actually agree with the main idea. I understand the arguments for 'Uncle Bobifying' code but I think, as the article says, there's a balance to be struck. It's highly likely the next time I see your code (or my code if I'm coming back to it a month or two later) is when I need to fix a problem with it. While it's useful to have it split up into logic…

Isnt this just 'good coding practices'? How is 'Avoid Indirection in Code' justified?

Re: Avoid Indirection in Code

#68

While the example in the article isn't great for making the point I actually agree with the main idea. I understand the arguments for 'Uncle Bobifying' code but I think, as the article says, there's a balance to be struck. It's highly likely the next time I see your code (or my code if I'm coming back to it a month or two later) is when I need to fix a problem with it. While it's useful to have it split up into logic…

Agreed, although I think the example isn't too bad. I often see such "helper methods" - usually in a class called "utils" or "misc" - when (novice) programmers "try to plan ahead": how should I write this so it can be re-used?

But KISS is remains a good principle. Predicting the future is hard. If in doubt, don't put in the extra indirection/abstraction. If/when the next person needs that functionality, they can refactor it - and the simpler/more straightforward the code, the easier it is to refactor!

When the logic is already split over multiple methods, refactoring in a different direction becomes harder. Often, it's enough to verify there's only one caller, and then stuff it back into one method before refactoring. Still, more annoying than if they hadn't of overthought it.

Re: Avoid Indirection in Code

#70

Okay, maybe it's just a poor example, but in the example used, the problem is definitely not too much indirection. If I was doing a code review and came to this: def is_foolike(x): return x.startswith("foo") I would comment, but my comment would be, "Could you name this function `starts_with_foo`?" This addresses both concerns mentioned in the article: 1. During review, when a reviewer is asked to verify that code is…

I very much disagree with you. "starts_with_foo" is a horrible name, because it only says how it is implemented, but doesn't convey any meaning or the intention of the function. When I read the code, I have to paus and think about why we do this. When I see a name like "is_foolike" I should have good enough understanding of the code that I know why we want to know if something is "foolike", and at that point, I should not have to worry about how it is implemented. It is only if I got reason to believe that there's something wrong with the function or when I review that particular function that I need to worry about the implementation details.

In addition, if we for some reason want to change what we mean with foo-like (say to "contains("foo"), we suddenly have to change all calls to the function, in addition to the defintion.

Post reply on HN