Procedure Hallo(n:Byte);
Procedure test;
Var p : Byte;
Begin
p:= 5;
end;
Begin
Writeln('Hallo, World ',n,'');
end;
[\code]
I always indent and comment the end of the nested procedures and it sounds like very bad design to have thousands of lines of code in one.There are two reasons to group instructions, they are:
Maybe code written without oop?
I always ... comment the end of the nested procedures
There are two reasons to group instructions, they are:
1. A group of instructions accomplishes a specific, well defined logical task.
2. A group of instructions is executed multiple times.
...
The top level function is broken down into a number of functions/procedures and those functions/procedures are then executed in a mostly linear fashion, I say mostly because some may be part of a loop or if statement or some other code that controls how or when the code is executed. When the programmer reaches that code and sees "SomeFunction(SomeParameter1, SomeParameter2...SomeParameterN), it is quite often necessary for the programmer to "jump" to where "SomeFunction" is implemented to refresh his/her memory to see what the code actually does. If there are 10,000 lines broken into small "acceptable" pieces to some programmers, that means the 10,000 lines are going to be broken into about 200 individual blocks of code. That also means that when the programmer is reading the top level function, he/she will have their attention diverted away from the mainline 200 times. Welcome to spaghetti code and jigsaw-puzzle programming.
The way it should be done is to have a way (a construct of some kind) to group code _inline_ so the programmer can see (and be told) that a sequence of instructions fulfills a specific logical purpose. This is also a way to have the convenience of inline variables without inline variables and local types and constants that is only applicable to a very short sequence of code.
Inline/anonymous functions/procedures _almost_ fulfill the characteristics of the construct I alluded to above but, very unfortunately they require a "()" to cause them to be executed (because they weren't really designed to be a grouping construct.)
10,000 line functions/procedures are a whole lot better, easier to understand and maintain than functions/procedures broken into hundreds of scattered pieces that have to be mentally re-assembled to see what the function does and how it does it.
IOW, today's commonly accepted and supported programming philosophy is: let's make sure to make the big picture as hard to mentally create as possible.
Although many of the optimizations listed in the paper are quite obvious, such as prewarming the CPU caches, using constexpr, loop unrolling and use of inlining, other patterns are less obvious, such as hotpath versus coldpath. This overlaps with the branch reduction pattern, with both patterns involving the separation of commonly and rarely executed code (like error handling and logging), improving use of the CPU’s caches and preventing branch mispredictions, as the benchmarks (using Google Benchmark) clearly demonstrates.
@440bx I’ve often resorted to putting parts of code into smaller procedures when I was particularly confused about something. It helps.
It does it easier to understand if you replace multiple lines of code that do a particular thing with a procedure. It makes for easier reading Looking at a few lines of procedure names in a loop.
I don't have the document references at hand but, there have been a fair number of studies that have demonstrated that the easiest "structure" for the human mind to understand is the linear structure.
IOW, Linear things are easy.
One important observation is that local procedures/nested procedures predate object pascal.
But if you were working through a sourcefile, would you rather encounter a function ReloadBackend() (referring to something elsewhere) or a hundred lines of inline code (no matter how well documented)?Why would I prefer to have the code in a place which is _not_ where it is used ??? The one thing I'd like to see is something like this:
The one thing I'd like to see is something like this:
function TopLevelFunction begin { statements } Group ReloadBackEnd begin { reload back end statements } end; { ReloadBackEnd } { <- if the group of instructions is more than what fits in one screen, approx 50 lines } { followed by whatever follows "reloadbackend" } Group NextLogicalGroup begin { statements } end; { etc } end; { TopLevelFunction }
What about this?I see that as a definite improvement over having the code "relocated" to some other place.
function TopLevelFunction begin { statements } {$REGION ReloadBackEnd} { reload back end statements } {$ENDREGION} { followed by whatever follows "reloadbackend" } {$REGION NextLogicalGroup} { statements } {$ENDREGION} { etc } end; { TopLevelFunction }
The IDE will then allow you to collapse these sections (and I think it even remembers which sections are collapsed?)
<snip> ... because it turned out that I need them somewhere else too.That's the reason the code should _not_ be nested, because it is used in multiple functions/procedures.
Being new, I find it hard to predict how code will evolve.I've been programming for 47 (maybe even 48 by now) years and, unless I am dealing with something easy or very similar to something I've written before, how the code will evolve is still hard to predict. In most cases, a nebulous idea is good enough.
On a few occasions I ended up "un-nesting" some useful tools which I initially thought are better off encapsulated and out of scope, because it turned out that I need them somewhere else too. Being new, I find it hard to predict how code will evolve.The simple answer to this is: Don't try to predict how the code will evolve, because eventually it will go in a different direction anyway.
Also, I do not see the improved readability with nesting procedures, it is quite opposite actually, to me anyway. Object's private/public sections kind of makes more sense, they are declared, and if they are also commented this is the most logical and clear, easier to find and review.That may be true, but if you only ever work in methods and objects, you restrict yourself in a different way, because now to access the methods you are bound to the object/class you are working in. This results for example quite often in putting code that has absolutely nothing to do with the datastructure of that class, into methods of that class, just because it is convinient.