Live data from Hacker News

Avoid Indirection in Code

matthewrocklin.com

211–220 of 220 posts

Re: Avoid Indirection in Code

#211
post #160

Earlier quoted context omitted.

Using an exception for authorization failures avoids TOCTOU security holes. Also, in many cases, there are intermediate layers of the call stack that don't have any useful contribution to failure handling; the best they can do is forward the failure return value up the stack. And if one part of an operation fails because of a lack of permissions, it is usually dangerous to continue processing without handling the fai…

This is interesting and compelling. I wonder about spambots though, when authorizing a service exposed to the web. Doesn't it get expensive pretty quickly when a bot decides to scan the site and floods it with requests that all exception?

Efficient handling of authorization failures is neither necessary nor sufficient to preventing such denials of service.

Re: Avoid Indirection in Code

#212

Earlier quoted context omitted.

Nothing is being abstracted here, and nothing is gained by indirection Making the rest of the function readable would be a win. If the two functions in the if-then are quite long, and if that clause appears in many places, then that could be a big win in the aggregate.

Such indirection requires readers to go look up the definitions of other things to understand the meaning of each function. The nice thing about abstraction is that we don't need to go look up the definitions (unless we're tracking down a bug that's in those parts!): we can read a line like `if checkHasPermission(x):` and get the gist of what's happening, and skip over it if we don't care about the permission system…

When done properly, a function/method should be clear in terms of intent at the point of call.

I will be the first to admit that proper-naming is most usually rather challenging .

Re: Avoid Indirection in Code

#213

Earlier quoted context omitted.

When the author used generic "foo" examples, it's hard to tell if there's meaning behind it or not. In a real example, there might very well be meaning behind it, perhaps his "foo" examples in his actual life are more like your "checkHasPermissions" example. But I think you're right that "abstraction" is the important concept here, which "indirection" is either a synonym for or one part of, depending on what you mean…

> In actual experience, I think most of us end up erring on the side of too much/too complicated abstraction ("over-engineering"), so when it doubt, it makes sense to try erring on the side of less abstraction, including duplicating code at times (do not let "DRY" be your only guide). Yeah, this. I've noticed a lot of younger engineers(myself included when I was starting out) have a tendency to try to avoid duplicati…

A short and sweet adage that I have always appreciated is: "USE before REUSE".

I cannot recall where I read it though -- it was quite a while back.

Re: Avoid Indirection in Code

#214
post #134

One very important reason to avoid this kind of unnecessary indirection is that it wrecks locality of reference for anyone reading it. They end up spending all of their mental energy on skipping around the codebase trying to follow the thread of execution, making it very hard to assemble a coherent picture of what the code's actually trying to do.

I like IntelliJ's "Quick Definition" shortcut for this. It allows me to see the definition of a function in a popup window so I can quickly glance at what a certain function does without the full context switch.

I've only spent a few weeks using IntelliJ but from that time it seemed like a really well constructed dev environment. Definitely gave me the feeling that this is what modern software development should be like.

Re: Avoid Indirection in Code

#215
post #209
post #125

Earlier quoted context omitted.

> The issue is fundamentally abstractions leak. Only people who've never used a good type system think this. Your function example demonstrates this pretty nicely: use a proper interval type for the two intervals and a proper return type rather than int, and then the answers to all your questions become obvious.

> use a proper interval type for the two intervals and a proper return type rather than int You can do that with a "bad" type system like C's, but types themselves are a leaky abstraction with many usage decisions needing to be aware of underlying details of the type. Should the variable be stack allocated? Depends on the size of the underlying type and whether it's static. Can I add a variable to this type? Depends…

That's not a leak, or if it is then the whole concept is meaningless. The abstraction of a decent type system is sound and true: any expression of given type really does have that type. Of course there are lower level details (that's the nature of abstraction), but any properties at the level of the abstraction will hold for any conforming low-level implementation.

Re: Avoid Indirection in Code

#216

Earlier quoted context omitted.

I'm just being a bit grumpy, but there are non-pure languages that aren't OOP, and there is no reason why you can't write OO code that is where all objects are immutable. However, it is a good point that mutability is a major problem. It's just not correct that this has anything to do with OOP.

Fore sure. I was painting a large brush and you can find instances of mutability in functional languages and subsets of OOP that are immutable. Things like value objects, the builder pattern, dependency injection, ...

Possibly you aren't aware, but both FP and OOP are orthogonal to mutability. There are lots of mutable FP languages (for example, the first one ;-) ). These days it is popular to make pure FP languages, but that was not the case 40 years or more ago. Similarly, Alan Kay had quite a lot to say about mutability in Smalltalk. I'm not aware of any pure OO languages, but very few people knew how to deal with persistent data structures until Chris Okazaki's PhD thesis on the topic ~1996, if I remember correctly. Mutability is really up to the programmer. Even in C++ you can have const data structures and even const functions -- which are guaranteed to be pure. C++'s mistake was that it didn't make const the default; a mistake that Rust corrected. Back in the 90's all of my C++ code had const strewn all over it -- it was on practically every line. It was really clear to those of us doing it that you had to separate your "const" code from your "non-const" code because if you ever decided to omit that "const", it would rot your entire code base in a very short time frame -- mutability is really contagious.

I know it's popular to hand-wave and say, "Well most OO programmers don't write immutable code and lots of design patterns depend on mutability so therefore OOP is defacto-mutable while FP is defacto immutable", but this really obfuscates the true nature of the issue. There are programmers who prefer to write mutable code (in any paradigm) and those who prefer to write immutable code. It's quite easy to write OO code in an immutable way and most statically typed OOP languages even give you tools to help you do it. The reality is that many programmers just don't care. Of course, those programmers never reach for a pure FP language, but there are still heaps of old school FP programmers who would never write immutable code (I know several personally).

Perhaps you knew all that as well, but if so, I would ask a favour that you don't say "OOP is mutable" because it is highly misleading for people who don't understand the issue well (and frustrating for programmers like me who enjoy writing immutable OO code).

Re: Avoid Indirection in Code

#217
post #206
post #100

Ok, to take a real world example instead: if (url.startsWith('http://')) { vs. if (isAbsoluteUrl(url)) { If the next developer comes by in 2 months to fix the case for https:// urls (and protocol relative ones in 6 months), they'll immediately be able to spot the intention of the code and can easily fix it in the abstraction layer that's already in place. Moreover, the fix will be applied every other place this fault…

Seems to me that this is a great example of how, if I'm the next developer, I will have to go dereference isAbsoluteUrl in order to see that the https:// case hasn't already been handled--whereas it would have been obvious with the inlined version. Maybe isAbsoluteUrl is imported from a module I trust, and I won't think to go look at it for the problem. And "every other place" is a bit of a strawman, since everyone c…

I never said you wouldn't have to dereference and check the implementation. That's debugging. I said that it would make my intent clear. That I wrote the code below that line with the assumption that url is absolute and not specifically only the 'http://' case. The abstraction here is about encapsulating and communicating my intentions.

Re: Avoid Indirection in Code

#218
post #214

Earlier quoted context omitted.

I like IntelliJ's "Quick Definition" shortcut for this. It allows me to see the definition of a function in a popup window so I can quickly glance at what a certain function does without the full context switch.

I've only spent a few weeks using IntelliJ but from that time it seemed like a really well constructed dev environment. Definitely gave me the feeling that this is what modern software development should be like.

I believe it is. The big thing that made IntelliJ completely click for me is when you buy the Ultimate edition and you download some plugins for Ruby,Node,Python or whatever languages you use you have a full IDE that works for pretty much any language.

In my eyes it is a platform for doing modern software development.

Re: Avoid Indirection in Code

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

> 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? How will the reviewer know if the abstraction is well-designed or named without reading it? Code quality attitudes change over time so sometimes the standard project-provided helpers end up not matching the intuitions of more recent contributors.

It’s a valid question, but at some point in a code review you have to trust an abstraction layer, lest you end up reading semiconductor physics papers for every PR.

Re: Avoid Indirection in Code

#220

Earlier quoted context omitted.

Such indirection requires readers to go look up the definitions of other things to understand the meaning of each function. The nice thing about abstraction is that we don't need to go look up the definitions (unless we're tracking down a bug that's in those parts!): we can read a line like `if checkHasPermission(x):` and get the gist of what's happening, and skip over it if we don't care about the permission system…

When done properly, a function/method should be clear in terms of intent at the point of call . I will be the first to admit that proper-naming is most usually rather challenging .

> When done properly, a function/method should be clear in terms of intent at the point of call.

Yes, of course, but that (I claim) implies that the function/method has abstracted something.

The parent was claiming that using indirection to hide code can be useful for readability, even when there is nothing being abstracted.

Post reply on HN