Why You Shouldn't Nest Your Code

Why You Shouldn't Nest Your Code

CodeAesthetic

1 год назад

2,570,656 Просмотров

Ссылки и html тэги не поддерживаются


Комментарии:

Joey Zhu
Joey Zhu - 26.09.2023 09:35

it's a tradeoff between complexity of ur dependencies versus the complexity within a single one. there is some conserved, lower-bounded amount of abstraction depth in whatever task you are trying to do. You're maximizing the intuitive information from the dependency structure and structure within each dependency, and minimizing the amount of clutter and chaos on either side(2nd law of thermodynamics applies to codebases), and your parameter is how many depths you go before you start making new files, and maybe also files to directories.

Ответить
Flodis
Flodis - 26.09.2023 02:34

Didn't know it, but apparently I, too, am a never nester. Is there an NNA (Never Nesters Anonymous) for us?

Ответить
2012TheAndromeda
2012TheAndromeda - 25.09.2023 23:28

The graphics are beautiful.. It very much helps see what's going on. The hows and whys as we are seeing whats happening is incredibly effective.. Thank you!!

Ответить
Jovan The Great
Jovan The Great - 25.09.2023 23:21

Hey bro idk if you read the comments, but in case you do, can you tell me how do you make your videos? What software did you use?

Ответить
Silver Fox
Silver Fox - 25.09.2023 22:22

I always do this and I never noticed before! Thanks!

Ответить
Georg Renelt
Georg Renelt - 25.09.2023 14:43

I confess i'm a nester because i usually prefer keeping code and conditions together to spreading it to fragments - even if modern ides support jumping around very well.

Ответить
Chris Ochieng
Chris Ochieng - 25.09.2023 08:27

Would inverting if (top>bottom) would have been if (top<=bottom)? or if you want a headache if not(top>bottom) 🤣🤣

Ответить
Z W
Z W - 25.09.2023 05:05

don't know why but I like this kind of videos.

Ответить
yo tu
yo tu - 25.09.2023 04:52

jip had the same feeling. the denested code is way more easier to understand/read. Pretty good explanation

Ответить
KhayyamAurelius
KhayyamAurelius - 24.09.2023 21:44

I am a flutter developer. I feel great pain every day.

Ответить
Stephen Fulton
Stephen Fulton - 24.09.2023 19:30

The next thing to consider is definition ordering. If you didn't write this code and you tried to read it, the control function (run) is the last function in the file. That's a problem for anyone that wants to use this object because they have to slog through the minutia of the object's private internal functions before they can get to the public usage. Public functions should be first with the private functions later in the file. A file ordering that is basically the exact opposite of the one produced in this video is more usable code.

Ответить
Spidyy
Spidyy - 24.09.2023 18:43

So it shows you still have a little amount of disgust to even write a simple function. Do you even like coding at the point? =p

Ответить
Smaug
Smaug - 24.09.2023 16:51

If nesting grows, just extract it into a method. The next person reading it will thank you. Most industry standards include a desirable level of cognitive complexity.

Ответить
EldorJ
EldorJ - 24.09.2023 07:05

Meanwhile JSX syntax: 😂😂

Ответить
MrBlc
MrBlc - 23.09.2023 21:44

There is only one thing worse then deep nesting - avoiding it at ANY cost.


In my job, I did a lot of maintenance of old code, some written by my coworkers, some written by ex. coworkers, and some brought by client, written by third party. And I saw everything - from 20+ levels of unreadable nesting to unmaintainable mess of function inflation created in attempt to avoid nesting.

First example in video is good example of latter one, especially in combination with bad naming. What does name of function "filterNumber" says to reader? Absolutely nothing! In video, it's on same screen, so you can just glance it and know what it does, but in practice, you would need to scroll to it, especially if it's called from more than one place. If it's named more descriptive, like "filterEvenNumbers", it would be less of the issue. If you will reuse it, it also reduces code repetition, which is also bonus.

Now, let's imagine naming is meaningful, what other issues I have with this style of code?

First, calling function from loop have performance penalty. In OOP, we often intentionally scarify performance for readability, reusability, easy of coding and easy of maintenance, and it's ok, but only if we achieve our goal.

Do you really thing that:
int filterEvenNumber(int number)
{
if(number %2 == 0)
{
return number;
}
return 0;
}

...
sum += filterEvenNumber(number);

is more readable than
if(number %2 == 0)
{
sum += number;
}

I wouldn't say it is.

In some more complex cases, I would agree, but in this particular case, no. Deeper nesting does cause more mental workload in reading code, but how much doesn't depend only on depth, but also on length of that block. "If something, just add two number together" causes way less workload than "if something, make this 25 lines calculation".

My rule of thumb is: Any block offending nesting levels limit is worth fixing if at least one condition is met:
- can be done easily without making expression that is hard to read (like special edge cases)
- is worth extracting to separate function (will be reused and does something more then onliner)
- is more than few lines of code (if you can say what it does at one glance, it doesn't pollute readers attention stack)

Extracting oneliner and calling function just to avoid nesting level where reader needs more attention to conclude what function returns than to evaluate that oneliner sounds like cheating.

Ответить
John Phamlore
John Phamlore - 23.09.2023 07:05

This is one of the most useful practical programming videos I have ever seen, and the irony is I am somewhat familiar with Linux kernel coding. Also the Linux kernel uses goto's to structure cleaning up functions.

Ответить
Eric
Eric - 21.09.2023 21:53

I like Torvalds guideline; the quote doesn't oppose nesting per se, but uses nesting as an indicator of Spaghetti code.

Ответить
Cary Galloway
Cary Galloway - 21.09.2023 20:13

Two CONS of going crazy about eliminating nesting:

1) it actually can make code harder to understand because you have functions that ONLY have one function calling it so you have to keep the context of that function in your head to understand their purpose.

2) performance. Function calls are expensive. They have to push all the local variables in the current function on the stack which is memory copies and jump to the new location of the function, allocate its variables and when it returns pop off the parent local variables off the stack again.

Too much nesting can be a warning sign though for a rewrite/rearrange/refactor and that can include moving out parts to another function, but seeing 2-4 depth nested code shouldn't really make you care that much at all.

Ответить
IllidanS4
IllidanS4 - 21.09.2023 19:23

I saw this video half a year ago, and while at first I thought it silly to just follow such an advice blindly, I can now say that it has had quite an influence on how I write code. I am still not a never nester though, because I feel the nesting level is only a rough estimate of complexity, which is what you are ultimately trying to eliminate. Sometimes breaking the code into 4 functions does not help in that if the code is really inseparable... something like brute-force searching a 4-dimensional space has natural nesting embedded in the problem, so it doesn't make sense to separate the individual levels into functions (you may however extract the logic of producing a sequence of 4-dimensional values that cover the space outside of the code that works with them).
That being said, I am now definitely more in favour of early returns which I had felt being somewhat discouraged.

My advice then:
At the high-level: handle exceptional state first (get rid of the nasty, gritty situations, validation and sanitization etc.), then lead the optimal path to the end of the function. If there are two or more optimal paths, then it becomes a candidate for extraction to functions.
At the low-level: favour early returns and early breaks/continues over nesting. Use switch when sensible since you can break out of it too. Don't fear using goto if that doesn't introduce complexity and reduces nesting.

Ответить
バンジョベンジ
バンジョベンジ - 21.09.2023 18:58

I don't think I've ever gone deeper than 3...

Ответить
Spital Helles
Spital Helles - 21.09.2023 06:38

I always try to find a mathematical function to replace if statements with

Ответить
Raven
Raven - 21.09.2023 03:35

the intro brought me so much pain

Ответить
jmw150
jmw150 - 20.09.2023 21:22

I use a semantic display, because I am not a CS 101 student. This stupidity can go in the tabs versus spaces trash bin.

Ответить
Robert Fox
Robert Fox - 20.09.2023 21:06

Now I see why I struggled on my highschool CS exam's last problem. I nested like 5 times and it was too much for my 17 year old brain.
P.S. Nonetheless I got the right answer :)

Ответить
Stenly Rachmad
Stenly Rachmad - 20.09.2023 18:12

So tell me how u do never nested in html? Hahaha

Ответить
thepizzacar pizza
thepizzacar pizza - 20.09.2023 10:06

I nest as far as I goddamn need to. My priority is code size. I nest as much as I need to keep the code in one string. Occasionally, I separate out complicated nests into a unique function, but I never make a function I won’t use more than once

Ответить
Dev
Dev - 19.09.2023 21:55

What about try/catch blocks, do they count as a nest? Almost seems unfair to include it.

Ответить
Juan Ignacio Borda
Juan Ignacio Borda - 19.09.2023 19:43

OMG I'm a never nester too and I dodn't knew!!!😆

Ответить
BT293
BT293 - 19.09.2023 18:18

Welp, time to nest 20 deep then

Ответить
Silently
Silently - 19.09.2023 17:28

Im into programming for 3 years now and after few projects, the maximum depth i go is 2 (most of the time i still go for a single if and almost never go for else)

Ответить
iain y
iain y - 19.09.2023 14:47

There are legit places to use 4 or 5 deep. Even for never-nesters.

Looping over pixels in an image (its a 3d array, so 3 loops are logical), then a couple if statements -eg for edge & corner pixels get you to 5.

Ответить
Jaeric
Jaeric - 19.09.2023 03:16

I've just started watching CS50 and it seems like this is exactly what David Malan meant when he talked about "abstraction".

It looks so much neater and tidier than all those deeply nested pits of hell. I'll try to learn coding just like you've shown from the start.

Ответить
91Canjok
91Canjok - 19.09.2023 00:19

This guys words come out as clean printed letters.

Ответить
Todd Barton
Todd Barton - 18.09.2023 23:48

I particularly like Extraction because then you can give the function really descriptive names, then when you read thru the top function it's almost like you're just reading a book, instead of interpreting the logical flow of the code. I often combine Extraction and Inversion, in that after I invert, I'll extract the inverted code into its own (descriptive) function.

Ответить
İsim bulamadım o beni bulsun
İsim bulamadım o beni bulsun - 18.09.2023 23:23

bruh one of my functions in the current class that I am working is ends like this "}
}
}
}
}
}
}
}
}
}
}"

Ответить
ttthttpd
ttthttpd - 18.09.2023 21:04

Fine, as long as you use good function names and type signatures.

Also, if you aren't one of those "more than 10 lines needs refactoring into multiple functions" weirdos.

Often, a linear chain of blocks + comments are easier to read than 100s of only-called-once functions with unhelpful names and dozens of parameters (or nested scope, or one-off structs)

Ответить
astral stern tarantoga
astral stern tarantoga - 18.09.2023 20:34

I was at a company where I found a function in their not so legacy code that had 600 lines and 14 levels of nesting. No one understood my disgust... But that's maybe not too astonishing when you see their 3000 lines headers that only commented on what the operator== meant to do. I'm so happy to have quit.

Ответить
Anton Sh.
Anton Sh. - 18.09.2023 16:50

I sometimes like having nested code, even if it's not necessary, when there is some straightforward and not very big problem to be solved. So, having a solid "brick-like" solution for it makes it seem simple and raw reflecting such nature of the problem itself.

Ответить
Fady Khalife
Fady Khalife - 18.09.2023 15:58

I always go balls deep when writing my functions!

Ответить
satibel
satibel - 18.09.2023 15:52

As an embedded/electronics programmer the "extract everything to functions that are used once" makes me uneasy, so much waste.

Ответить
MD
MD - 18.09.2023 12:58

This is how I refactor but have never been able to articulate my process as well as this. Impressive job!

Ответить
MrBiggles53
MrBiggles53 - 18.09.2023 11:21

There are dozens of, Michael. Dozens!

Ответить
Thomas Slone
Thomas Slone - 18.09.2023 05:25

i write my code to function and be readable by me years later,that's all

Ответить
Waffle
Waffle - 18.09.2023 04:02

It also makes testing much easier and you can isolate different pieces and paths

Ответить
Luke DiGiovanna
Luke DiGiovanna - 18.09.2023 03:09

I honestly thought this was just implied in good coding standards. I never declared myself a "never nester", but this is exactly how I write my code in the first place simply because it makes it so much more comprehensible.

Ответить
GoatZilla
GoatZilla - 17.09.2023 21:23

The curiosity is what these reorgs cause the compiler/interpreter to do with your code.

Ответить