Комментарии:
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.
ОтветитьDidn't know it, but apparently I, too, am a never nester. Is there an NNA (Never Nesters Anonymous) for us?
Ответить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!!
Ответить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?
ОтветитьI always do this and I never noticed before! Thanks!
Ответить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.
ОтветитьWould inverting if (top>bottom) would have been if (top<=bottom)? or if you want a headache if not(top>bottom) 🤣🤣
Ответитьdon't know why but I like this kind of videos.
Ответитьjip had the same feeling. the denested code is way more easier to understand/read. Pretty good explanation
ОтветитьI am a flutter developer. I feel great pain every day.
Ответить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.
Ответить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
Ответить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.
ОтветитьMeanwhile JSX syntax: 😂😂
Ответить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.
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.
ОтветитьI like Torvalds guideline; the quote doesn't oppose nesting per se, but uses nesting as an indicator of Spaghetti code.
Ответить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.
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.
I don't think I've ever gone deeper than 3...
ОтветитьI always try to find a mathematical function to replace if statements with
Ответитьthe intro brought me so much pain
ОтветитьI use a semantic display, because I am not a CS 101 student. This stupidity can go in the tabs versus spaces trash bin.
Ответить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 :)
So tell me how u do never nested in html? Hahaha
Ответить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
ОтветитьWhat about try/catch blocks, do they count as a nest? Almost seems unfair to include it.
ОтветитьOMG I'm a never nester too and I dodn't knew!!!😆
ОтветитьWelp, time to nest 20 deep then
Ответить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)
Ответить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.
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.
This guys words come out as clean printed letters.
Ответить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.
Ответитьbruh one of my functions in the current class that I am working is ends like this "}
}
}
}
}
}
}
}
}
}
}"
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)
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.
Ответить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.
ОтветитьI always go balls deep when writing my functions!
ОтветитьAs an embedded/electronics programmer the "extract everything to functions that are used once" makes me uneasy, so much waste.
ОтветитьThis is how I refactor but have never been able to articulate my process as well as this. Impressive job!
ОтветитьThere are dozens of, Michael. Dozens!
Ответитьi write my code to function and be readable by me years later,that's all
ОтветитьIt also makes testing much easier and you can isolate different pieces and paths
Ответить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.
ОтветитьThe curiosity is what these reorgs cause the compiler/interpreter to do with your code.
Ответить