Anonymous functions - Errors with scoped variables - (local and global variables).
Edit: I tried it intensively, also with some modifications. Seems to be completely solved. Thank you!! ========================================================================================= Edit: I updated to: ``` Verbose: Free Pascal Compiler version 3.3.1-12784-gb9aeeaa6e3 [2023/06/21] for x86_64 ``` The problems vanish with ``{$mode delphi}``, but persist with ``{$mode objfpc}``. This Issue replaces #40315. I describe the remaining problems in better detail here. So #40315 is closed now. I get various errors with the same source. The errors change when I change variable declarations. _All these declarations, which do not compile, are syntactic correct_. **Example:** The following source is _exactly_ equal, only difference: I removed the (unused) local variable "str". This results in compile error: ``` project2.lpr(41,25) Error: Overloaded identifier "__FPCINTERNAL__ANONYMOUS_2" isn't a function ``` ```pascal program project2; // This program compiles and runs in Delphi and in FPC. (at least should run in FPC) // It is intentionally designed this way. {$ifdef FPC} {$mode objfpc}{$H+} {$modeswitch functionreferences} {$modeswitch anonymousfunctions} // {$warn 5036 off}// "Warning: (5036) Local variable "$Capturer" does not seem to be initialized" {$endif} // uses {$IFDEF UNIX} cthreads, {$ENDIF} // Classes, Sysutils { you can add units after this }; type T_X = String; // Type of Test-variable X TfuncS = reference to function: T_X; TfuncF = reference to function(s: T_X): TfuncS; var f_inner: TfuncS; f_outer: TfuncF; //------------------------------------------------------------------------------ procedure caller; begin f_inner(); end; //------------------------------------------------------------------------------ procedure main; var X: T_X; // str:String; f_outer: TfuncF; begin X := '1234'; f_outer := function(s: T_X): TfuncS // This captures local and persistent copy of "X" begin Result := function: T_X begin Writeln(s); Result := s; end; Writeln('Outer function was called'); end; f_inner := f_outer(X); // This instantiates the outer function and f_inner and captures their local context. X := '0'; // Erase the T_X content Writeln('now calling f_inner'); caller(); // This line prints the T_X s=1234, which was captured by the outer function. // f_inner will be called from an external context, this is just for test and demonstration end; //------------------------------------------------------------------------------ begin main; Writeln('Now the context of "main()" is lost. Can we still print the variable "X"?'); if f_inner() = '1234' then Writeln('Yes! :-)') else Writeln('No! :-('); readln; end. ``` **New Example:** This source is equal again, I removed only the local variable "f_outer" and it should now use the global variable with same name instead. This gives the same compile error. Strangely, if I then also remove the _unused_ local variable "str", it compiles and runs. ```pascal program project2; // This program compiles and runs in Delphi and in FPC. (at least should run in FPC) // It is intentionally designed this way. {$ifdef FPC} {$mode objfpc}{$H+} {$modeswitch functionreferences} {$modeswitch anonymousfunctions} // {$warn 5036 off}// "Warning: (5036) Local variable "$Capturer" does not seem to be initialized" {$endif} // uses {$IFDEF UNIX} cthreads, {$ENDIF} // Classes, Sysutils { you can add units after this }; type T_X = String; // Type of Test-variable X TfuncS = reference to function: T_X; TfuncF = reference to function(s: T_X): TfuncS; var f_inner: TfuncS; f_outer: TfuncF; //------------------------------------------------------------------------------ procedure caller; begin f_inner(); end; //------------------------------------------------------------------------------ procedure main; var X: T_X; str:String; // f_outer: TfuncF; begin X := '1234'; f_outer := function(s: T_X): TfuncS // This captures local and persistent copy of "X" begin Result := function: T_X begin Writeln(s); Result := s; end; Writeln('Outer function was called'); end; f_inner := f_outer(X); // This instantiates the outer function and f_inner and captures their local context. X := '0'; // Erase the T_X content Writeln('now calling f_inner'); caller(); // This line prints the T_X s=1234, which was captured by the outer function. // f_inner will be called from an external context, this is just for test and demonstration end; //------------------------------------------------------------------------------ begin main; Writeln('Now the context of "main()" is lost. Can we still print the variable "X"?'); if f_inner() = '1234' then Writeln('Yes! :-)') else Writeln('No! :-('); readln; end. ```
issue