Here, I managed to reproduce.
Put breakpoint ono "result := localInt;", ok when 10, lands there.
Do not remove break point, press F9, observe localInt value, goes backwarda 9,8,7,.....
Well that is expected and correct.
If you open the "Call Stack" window from menu "View > Debug Windows" then you can see some more details.
Here is what happens
Line 14; "f(1);"
Line 7: "localInt := j +1;" value = 2
Line 8: " if localInt < 10 then" is true
Line 9: " f(localInt);" recursive call
Entering RECURSION,
- there is a NEW variable localInt
- localInt of the outer call will not be modified
Line 7: "localInt := j +1;" value = 3 for the NEW localInt
At this point the OUTER LOCALINT is still 2
Line 8: " if localInt < 10 then" is true
Line 9: " f(localInt);" recursive call
Line 7: "localInt := j +1;" value = 4 for YET ANOTHER NEW localInt
At this point there are TWO outer LOCALINT with values 2 and 3
Line 8: " if localInt < 10 then" is true
Line 9: " f(localInt);" recursive call
.....
When you finally hit
Line 11: " result := localInt;"
That is the innermost recursive call, and the value is 10
Then each F9 goes OUT one level of recursion, and each outer call has its own variable "localInt", which is one less than the inner one.
So you get down until "localInt = 2" => which is the value it had in the very first entry of "f".
In the stack you can see how many callers there are, and you can see the value of the parameter "j".
You can select any frame (line) in the stack as "current", and then you can inspect "localInt" for each frame. And you will see that all the values are there from 2 to 10.
While if you put additional breakpoints anywhere, looks like everything that happens is on "breaked line" and nowhere else.
Obviously there is no - anywhere.
If you put the breakpoint before line 9 or on line 9 (where the recursive call happens) then the recursion has not yet entered, and you will watch going into it. SO things happen in the order of going in.
And it does not go out as said at OP, when one would expect.
The 0 instead of 10 comes out even if there are no breakpoins.
Actually 2 comes out? At least for me?
How to fix that ?
procedure TForm2.Button22Click(Sender: TObject);
function f(j: integer): integer;
var
localInt : integer = 0;
i: integer;
begin
localInt := j +1;
if localInt < 10 then
f(localInt);
result := localInt;
end;
begin
f(1);
end;
Maybe you want code like
function f(j: integer): integer;
var
localInt : integer = 0;
i: integer;
begin
localInt := j +1;
if localInt < 10 then
localInt := f(localInt);
result := localInt;
end;
or
function f(j: integer): integer;
var
localInt : integer = 0;
i: integer;
begin
localInt := j +1;
result := localInt;
if localInt < 10 then
result := f(localInt);
end;