@Martin_fr
I would not assume that inline variables are useful only when writing spaghetti code and/or the function body is too long.
For a function of only 10 lines of code, if you realize you need a new variable, you have to press arrow up ten times, and then arrow down ten times, looking at where the cursor is. These are 20 keypresses. Or you can lift the hand to grab the mouse (where is now the mouse pointer? Ah! Up there...), and click in the right place. Then move the mouse pointer away because that cursor seems an uppercase "I". And then write your declaration, and then grab the mouse again to return in the previous spot.
l
All this would be alleviated by Ctrl+Shift+C, TY again mr. LV.
Assuming the most basic editor (so you have no quicker way than 10 time the up key), then you also don't have code completion, or anything but the compiler (and yourself) that relies on the declarations.
So when you write a line of code with a new variable, you keep on writing code => you don't go to declare it just now.
Once you got your 20 to 30 lines of code (which should fit onto a screen), you do a good job and re-read what you just wrote (that is a good idea on its own). While you do that you can have the cursor in the "var" block, and add the variables.
At the same time, you will have a chance to notice, if any variable could be named better, is not required, should be split into two vars ....
If you use the Lazarus IDE (which you don't have to) then you may have added vars with ctrl-shift-C (because code completion works only once the var is declared). But then you still want to do that review.
If you use an other editor, it may still have bookmarks and other navigation features to make that less keystrokes, if you want to add vars more frequently.
And you can (within reason) reverse the process partly
start := GoGetFirst();
cnt := GoGetCount();
for i := start to start+cnt-1 do
...
When you add "start", you already know you need "cnt" and "i".
Mind you,
I am not saying there is never a case where you would have code requiring you to go up/down more often than desirable.
But, that should be a rare-ish occurrence.
And, IMHO it does not make enough of an argument for inline vars. It just can't be the goal of any language to have tons of features added for each and every last minor case of how code occasionally may look like.
(Yes, I realize I am not the authority on how your code must look like... But, as I also said before: Every language (not just Pascal) has an impact on how code written in it will look and be structured. I have been at the point were I tried to write Pascal in the style of other languages, and that just was bad in every way, Pascal did not support those styles. In a sense, even Delphi now is a different language. I can't judge what influences your style, but give it some thought, please)
And as I pointed out, inline-vars are not free of cost (not speaking of the maintenance of the compiler sources / but of the negative effects it can have on the user code). And those effects are affecting everyone. There is no opt out, everyone will be faced with reading code of others.
E.g. my earlier example:
var foo: integer; // global / but could be class field / even in a diff unit
// in some cases (not below) it could even be a function
{...}
procedure bar;
begin
{...}
foo := CurrentFoo();
{...}
if ... then begin
var foo: integer;
{...}
DoWork(foo); // ups, you do not work on CurrentFoo
end;
if ... then begin
{...}
DoWork(foo); // ups, you do not work on the local var
end;
end;
Especially if one doesn't use Lazarus with code navigation, then one can't easily find that declaration. So then one would be screwed.
(I don't have Delphi, I can't verify the example, but I am sure something like this can happen, even if it needs a bit different setup)
So then, the cost must be compared
- New source of errors
versus
- Bit more work to declare the vars
(if you use an editor that does not help you, and depending on how you organize your code)
Mind that outside the IDE, you could still have editors that help you
- bookmarks are common and can help navigate between code and var block
- user definable macros exist in several editors, they could do the navigation, or even more
The real problem I see is this: I think that "declare all variables before the body function" was also done to help the compiler (a one-pass compiler). Moreover, having all variables declared in a single point seems (and *can* be) a "clean way to structure the source", but is not always so. That single point of declaration can be polluted by implementation details which subtract diminish clarity instead.
That it may also help the compiler is not a reason against other benefits it has.
Besides, "inline" can be done as a single pass, but then you need to dynamically change the allocation of the stack frame.
Take this excerpt from IniFiles.pas (which was not written by me...; it took me less than 2 minutes to find a suitable example):
function TCustomIniFile.ReadBinaryStream(const Section, Name: string; Value: TStream): Integer;
Var
M : TMemoryStream;
S : String;
PB,PR : PByte;
PC : PChar;
H : String[3];
i,l2,code : Integer;
Talking about clarity, the VAR section seems to me quite useless, especially the declaration of PB, PR, H, i, l2. Looking at function body I see that the really relevant vars are M, S and PR.
But wait! M is not even used! So the VAR block is also misleading...
I am too lazy to do it, but I am (very) convinced that the TCustomIniFile.ReadBinaryStream function, using inline variables, would have been written faster, with less effort, and more clarity. That's all.
Well, you can declare a variable inline, and then not use it. So for that it makes no difference.
The real problem I see here, is the choice of names for the variables. If you have that many (or if your code is more than a few lines) then they should have more meaningful names. That helps making the code more readable.
And of course, meaningful names can be given with or without inline vars.
But, with pre-declared vars, there may be a nice workflow, helping with meaningful vars. Well at least there is
a workflow that I like very much.
- While writing code (and things still change a lot), I use short meaningless names (I may end up with completely unreadable i,j,k,l,m,n,o,p vars).
- When I have enough code (not necessarily all done), I use syncre-edit (several editors have that / but search replace also does the job). And I rename the variables.
So the one major difference is:
- Pre-declared gives me a nice list in one place, which I can (have the option to) use to rename them into something more meaningful.
- inline means I have to search for each var I introduced. Much more work, and higher chance to miss one.
And well, sometimes I forget or am lazy. But inline vars wouldn't change that.