DEV Community

loading...

Discussion on: Why limit function size?

Collapse
anders profile image
Anders

I don't have a line limit at all, it doesn't make any sense. A better limit is a complexity limit IMHO.

I think Carmack has some interesting reflections on this, its a long read but a good one: number-none.com/blow/john_carmack_...

Collapse
winstonpuckett profile image
Winston Puckett Author

This reply is getting long, and the thing I am really curious about is, how would you go about enforcing a complexity limit? I'm super curious and hope to learn something here.

I have more thoughts ... But again, I realize they're kinda long lol.
About the post:
I think the point I was attempting to make above is that line limits can point to problem decomposition and abstraction problems if they're taught alongside each other.

When you comment large your code instead of moving it to a separate function, I think that sudo-subfunction becomes the place where line limits could be enforced :)

Thoughts on the link:
That was an interesting read. I think the claim that "style c," as John puts it, makes code cleaner is false. The code base I live in right now uses style c and still has lots of duplicated code and unnecessary complexity. For instance, there's a variable called "isPoChanged" on line 3 and a variable called "isPOChanged" on line 500 that is entirely different. They're in the same scope and get used throughout the rest of the function.

I like what he said here:

"If something is going to be done once per frame, there is some value to having it happen in the outermost part of the frame loop, rather than buried deep inside some chain of functions that may wind up getting skipped for some reason."

Collapse
anders profile image
Anders

I think your variable example there certainly would qualify as a place where you would benefit from splitting it into multiple functions =)

But it doesn't really relate to the LENGTH of the function, it's more about what it does, the number of variables and concepts that are in the function.

At the core code should do two things:

  1. Work
  2. Be easily understood.

We have functions that are 100:s of lines long, and that is fine because the flow is simple to follow. We do use comments for “sections of code” that could be moved into sub functions, this is to make it more easily parsed by a human.

Some cases where you definitely want sub functions:

  • There is a lot of “local state”, especially if there is very little shared state with the “root” function.
  • There are multi level nested conditions and or loops
  • A non trivial part of the code is repeated multiple times, ex: you need to format a date a certain way, that happens 12 times, sub function that. If it happens twice, and the code to do it is very simple, probably inline it.

Imagine a simple case where we have a function that renders a simple view in a web app, it creates a list of three different types of things, each of these is rendered entirely differently from each of the others, but it is the same view, and the output is very simple. For each collection we have 20 lines of presentation logic. Applying an arbitrary “max 40 lines per function” forces this to be split into 3 functions (or a real weird set of 2 ; ). Forcing the person who modifies the view to handle 4 functions (root and sub functions). And provides no actual benefit compared the “C” style as outlined by Carmack.

But as always, it's always about trade offs. And I don’t think there are any “hard rules”. You and your team need to find what is reasonable for you.

Thread Thread
winstonpuckett profile image
Winston Puckett Author

Thanks for explaining :). It's funny, the other day I was playing with a nav menu in Blazor and ran into that situation.

I definitely agree that "do what makes sense" is more important than an arbitrary rule.