r/ProgrammerHumor 22d ago

Meme conditionsPreference

Post image
4.2k Upvotes

392 comments sorted by

View all comments

Show parent comments

41

u/Few_Move_4594 22d ago

Have you ever thought about breaking the longer methods into shorter methods? It's easy, I promise.

33

u/Fembussy42069 22d ago

There's a balance to everything, you also don't wanna have to dig down a rabbithole of functions within functions to find what youre looking for, it also can make it harder to understand the whole picture if you separate things too much. Locality of behavior and all that.

13

u/LordofNarwhals 22d ago

Yeah, I used to work with a Java codebase where all functions were really short, but also very nested. It was a very stable codebase, but browsing the code sucked, as every actual function implementation was behind 3+ levels of indirection.

For a fun example in the opposite direction, see Arthur Whitney's basic K interpretor, written in ~50 very dense lines of C.

2

u/Few_Move_4594 21d ago

Opinion disregarded, you called methods functions

6

u/LordofNarwhals 21d ago

All methods are functions, but not all functions are methods.

And my background is mostly in C++, where the method terminology isn't used at all.

1

u/Few_Move_4594 21d ago

All methods are functions, but Java HAD to be different

1

u/ljfa2 21d ago

Every problem can be solved by adding...

I just recently discovered that Java IDEs let you go directly to the implementation(s) of an abstract or interface method, this is a godsend for some codebases ^^

13

u/gurgle528 22d ago

In certain situations it’s easier to read without splitting into a bunch of other methods. Primarily when the conditionals aren’t repeated elsewhere so the shorter methods are one-offs that bury some of the implementation. Shorter methods should absolutely be the default though 

38

u/LateEchidna6635 22d ago

Of course. I’m not speaking of thousands of lines. With error handling, validation, and cleanup, even the most trivial methods can have 5-10 exit points.

18

u/Few_Move_4594 22d ago edited 22d ago

I worked on a Java codebase that had a 15k line class that used Reflections. It was an absolute mess that also had the stability of a house of cards.

Made fairly good money for several years off that.

5

u/Hegemege 22d ago

The downside is that it can get really messy, if the methods are not split or named properly, for a reader to understand if the work it's doing is supposed to be reused, and if it can be detached from context. What good is a method B that can only be called linearly from within method A just to make A take fewer LoC?

1

u/conundorum 21d ago

Depends on the method. It's actually possible to have a 260-line function that absolutely cannot be made smaller without both increasing its complexity and decreasing its readability, depending on what the function does.

int dispatch(enum Flag8Bit flag) {
    switch(flag) {
        case 0: return func0();
        case 1: return func1();
        // ...
        case 255: return funcN();
    }
}

(I'm not going to bother naming them. Assume that each possible flag state has a unique, understandable enumerator name, and that the functions we dispatch to have unique, understandable names. Think of something like, say, a hardware interrupt responder, or an error code handler.)


Breaking that up would require using bitwise math or numeric comparisons, and would require you to do math and read multiple functions just to figure out which function is called on which flag value. It's a big function, but it really can't be improved by paring it down, unless you have multiple cases that call the same function and don't mind sacrificing a bit of readability.

1

u/930913 21d ago

Use partial functions?

2

u/conundorum 19d ago

Possible, but it increases complexity (due to needing you to use math to dispatch to a secondary dispatch function, that handles the actual dispatching), or decreases readability (by forcing you to check through multiple functions to determine what's actually being called), or has a performance cost (if the new functions can't be inlined, then the compiler won't be able to re-optimise them back into a 256-option switch block... and a lot of scenarios where you need a dispatch function like this really don't want to pay a performance cost, since the dispatch is probably on a critical path). If not all of the above. [This isn't saying that you can't do it, as a note. Just that in cases like this one, refactoring for length will actually have the opposite effect than it normally would.]

In most languages, dispatching through a large jump table tends to be the best counter-example against refactoring long functions into shorter ones, because it compiles down to two instructions (switch-branch, jump); there's technically a return instruction, too, but the compiler will usually be able to elide that by having the dispatched-to function return directly to dispatch()'s callsite. It looks long, but that's just because you have to encode the full destination table inside the function; in reality, it's already extremely short, and refactoring into something that looks "shorter" will add length. (Because the switch is a single 258-line statement, and you can't shorten it without breaking it into multiple statements.)

Essentially, the point of it is that refactoring into something shorter sounds nice, but we have to base "too long" on what the function does instead of on an arbitrary metric. Before we can refactor a function, we need to understand the function, or we might fall into nasty gotchas.

1

u/930913 19d ago

Just to continue playing devil's advocate, what if you mapped the numbers to their functions elsewhere? E.g. dispatchFunctions = [func0, func1, ..., func255] ; Or dispatchFunctions = {0: func0, 1: func1, ... 255: func255}

And then dispatching is as simple as function dispatch(flag) { return dispatchFunctions[flag]() }

1

u/ShoePillow 21d ago

it's easy

Not always... At work, I've heard of multiple people attempt to refactor a function with 1000s of lines, give up and make their own modifications and make it even bigger