Live data from Hacker News

Avoid Indirection in Code

matthewrocklin.com

71–80 of 220 posts

Re: Avoid Indirection in Code

#71
post #27

Earlier quoted context omitted.

It doesn't matter how good your abstraction is, if someone needs to know the details it is at that point indirection. And there will always be some cases where someone needs to know the details. The better your abstraction, the less often. But someone, sometime, will still need to look at them.

True, there will always be people who need to know the details. That applies all the way down to CPU opcodes. I’m making more of a semantic point than anything else. If you define indirection as anything which causes you to jump from the code directly in front of you at any point, then yes, you can call even good abstractions indirection. I’d argue that such a definition makes the word “indirection” must less useful,…

[deleted]

Re: Avoid Indirection in Code

#72
post #51
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):…

I agree with you. I think it becomes pretty clear when applied to the example in the article of code review. If the abstractions are designed and named well, why should the reviewer need to jump to the declaration of the function in the if statement? Assuming the checkHasPermissions function wasn’t added or modified in the PR, the reviewer should just consider whether it makes sense to do_something if and only if che…

You'd think so, but abstraction names are like comments: they are seldom updated when the implementation grows more hairs.

In older code, or code worked on by a larger team, I always chase into functions to understand the code, and don't rely on names. I'm also less inclined to indirect code unless the abstraction has genuine meaning, rather than being a compression technique for repetition, no matter how well named.

Re: Avoid Indirection in Code

#73
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):…

Agreed. I remember it as: "show what the code does, not how it does it".

Re: Avoid Indirection in Code

#74

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…

The issue is fundamentally abstractions leak. And if the code is overly "Uncle Bobified" the abstractions will leak bugs. On the other hand if you under "Uncle Bobify" the code will be very difficult to read because you won't be able see the forest for the trees. This is one of the advantages of comments and local functions. You can inline a function an add a comment. With the comment providing the abstraction and the line of code providing the details. Or add a local function which is easy to read but can be easily seen next to the code that's using it.

For instance you might have a function that is int getOverlap(DateTime start1, DateTime end1, DateTime start2, DateTime end2). Looks pretty reasonable. But there are a lot of unanswered questions like

Is the return value in seconds, minutes or ms? What happens if there is no overlap? Do all the date time have to be in UTC? What happens if we pass in a start time before the end time? What happens if I pass in a start time equal to an endtime? If I split a block will the overlap of this block with any other block match the combined overlap of any two split blocks?

Re: Avoid Indirection in Code

#75
My mental benchmark for the cost/payoff of indirection is usually

> Would this code be easier to read if A) I inlined the code or B) I replaced it with a descriptive function name.

Function could be read as Class or Method if you're dealing with OOP.

One important criterion for this is that other programmers already know the language, not your program. Writing your own function can help to put a meaningful name on a set of behaviors, but it also means the introduction of a new specific set of behaviors the reader needs to keep in the back of their mind. It's kind of similar to Jakob's Law [1] in a way, but applied to source code. (In a way, source code readability in't all that different from UX, if you think about it)

[1] https://lawsofux.com/jakobs-law

Re: Avoid Indirection in Code

#76
post #11

Earlier quoted context omitted.

While I can agree with the sentiment, when is indirection okay vs. when does it become spaghetti code? Given [1], there needs to be a happy medium between 12 layers and all in a single method. I think with less experienced developers, the issue is diving too deep because they think they need to prove they aren't novices. However, its still a learning period for them where they just need a good mentor to tell them the…

My rule of thumb is 3 times. Whatever is abstracted away must be used at least 3 times. It's amazing how much preemptive prettification by abstraction it prevents.

Abstraction is not mainly about avoiding repetition though. It's about (well...) creating abstraction.

Imagine if you have to check permission to do something, and that check is really complex and long code.

If would be better to have code like: if (hasPermissionToEdit(myUser)){ ...

Than a ton of ANDs and ORs in that if, that nobody would quickly recognize as a permission check... even if it's just there once.

As a minimum I'd put that in a properly named variable first, if I really wanted to avoid an extra function.

Re: Avoid Indirection in Code

#77
post #66
post #58

Earlier quoted context omitted.

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).

If you read my top level comment on this thread, you’ll notice I am saying exactly that — over use of anything is bad — as is inappropriate use.

Re: Avoid Indirection in Code

#78
post #72
post #51

Earlier quoted context omitted.

I agree with you. I think it becomes pretty clear when applied to the example in the article of code review. If the abstractions are designed and named well, why should the reviewer need to jump to the declaration of the function in the if statement? Assuming the checkHasPermissions function wasn’t added or modified in the PR, the reviewer should just consider whether it makes sense to do_something if and only if che…

You'd think so, but abstraction names are like comments: they are seldom updated when the implementation grows more hairs. In older code, or code worked on by a larger team, I always chase into functions to understand the code, and don't rely on names. I'm also less inclined to indirect code unless the abstraction has genuine meaning, rather than being a compression technique for repetition, no matter how well named.

Then the problem here seems like the lack of drive towards intention-revealing naming. It's burdensome, but worth it when the intention is revealed and prevents the navigation to the implementation.

But like the author said, the reuse fallacy prevents this from having a good RoI until there is a significant usage of said abstraction.

Re: Avoid Indirection in Code

#79
Like everything else you need to consider the context. I was involved in a rather big internal automation project written in Python, it involved a few platforms and targets and was ran open source style where each team could hook up to the infrastructure independently or make changes to it using PR.

Some of the code ran remotely using RPC, so part of the code sat in different repositories.

Naturally this called for multiple levels of abstraction and indirection. The results ? a big ugly pile of levels if you are trying to understand what the code does, that led to bugs, unnecessary complexity since it's hard to foresee the future and always abstract the way the code will need and the worst was that people simply gave up on trying to contribute do to the complexity of the otherwise simple code.

Re: Avoid Indirection in Code

#80
The main point here is worth a broader discussion. Part of the problem is that we tend to hide behind mental concepts that a ambiguous, incomplete or just bad.

DRY is a awful "thing" (a decree at best). In the worst interpretation it simply says "never write the same code twice". There is no balance or end to it. It doesn't have a competitor or alternative. It somewhat implies that it is always good. It doesn't define a scope where/when it should be applied. There is simply no broad agreement how to use it in practice. DRY touches multiple concepts, each too complex to put behind three tiny letters.

OP fails to make a great point, but the direction is right. We cannot take DRY and "code reuse" laws as granted. Abstractions and indirections have their downsides. It increases systemic complexity and may add dependencies. It certainly limits how easy the full system can be understood by humans.

Post reply on HN