Consider this standard (ISO) Pascal code:
program test(output);
procedure call(n: integer; function f(n: integer): integer);
begin
writeln(f(n))
end;
function f(n: integer): integer;
begin
f := n;
if n > 0 then call(n - 1, f)
end;
begin
call(3, f)
end.
The output should be
0
1
2
3
This compiles fine with {$mode iso} using FPC's trunk version, but can it be translated to {$mode fpc} or {$mode objfpc}?
The main difference AFAIK is that these modes require @ to distinguish procedural/functional types from procedure/function calls (and in some cases, but not here, () to do the opposite). We should also need {$modeswitch nestedprocvars}, since it should work with nested procedures/functions too, and procedure "call" uses a functional parameter.
program test;
{$modeswitch nestedprocvars}
procedure call(n: integer; function f(n: integer): integer);
begin
writeln(f(n))
end;
function f(n: integer): integer;
begin
f := n;
if n > 0 then call(n - 1, @f)
end;
begin
call(3, @f)
end.
But this results in an error
Error: Incompatible type for arg no. 2: Got "Pointer", expected "<procedure variable type of function(SmallInt):SmallInt is nested;Register>
referring to @f. It makes sense, since f is the function result variable inside function f, @f might be a pointer to the current function result.
Is there another way to get a functional variable/function pointer from inside the same function when using {$mode fpc} and {$mode objfpc}? In other words, is there a way to specify I want a function variable for the function named "f", not a pointer to the function result variable named "f"?