Test program about functional programming in FPC Trunk - various problems, documented in the source
Edit: The problem with datatype "String" is resolved. There are remaining problems.
I created a new issue #40324 (closed) which describes these in better detail. Therefore this issue here is closed.
===============================================================================================
This program is made to test a concept to capture variables by value (not by reference), which was demonstrated by embarcadero and Boian Mitov in some tutorial videos on Youtube.
The concept is: The outer anonymous function captures a value, and the inner nested anonymous function uses this value and can use it again at a later time at any time and from any context, even from a thread.
https://youtu.be/HDhmUjzUNyQ?t=1922
Please read the discussion below. The problem is NOT strictly related to the datatype "String". The program can be converted to use integers instead. Then, most errors stay the same and some other compiling errors turn up.
I have marked error locations by "// <---- Describing text"
program project1;
//This program compiles and runs in Delphi and in FPC. (at least should run in FPC)
//It is intentionally designed this way.
//It compiles without errors or warnings in Delphi and delivers the expected result.
{$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 TfuncS = reference to function:String;
TfuncF = reference to function(s:String):TfuncS;
var f_inner: TfuncS;
f_outer: TfuncF;
procedure caller;
begin
f_inner();
end;
procedure main;
var str: String;
// f_outer: TfuncF; // <---- doesnt compile in FPC when this is uncommented, but compiles and runs ok in Delphi
begin
str := 'Hello World!';
f_outer := function(s:String):TfuncS //This captures local and persistent copy of "str"
begin
Result := function:String // <---- Access violation here, when Line "Result:=s" is commented out and when it is compiled.
begin
Result := s; // <---- project1.lpr(37,9) Error: Internal error 2011010304
// if the line is commented out it compiles, but gives access violation at runtime
Writeln(s);
end;
Writeln('Outer function was called');
end;
f_inner := f_outer(str); //This instantiates the outer function and f_inner and captures their local context.
SetLength(str,0); //Erase the string content
Writeln('now calling f_inner');
caller(); //This line prints the string s="Hello World!", 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 string "str"?');
if f_inner()='Hello World!' then writeln('Yes! :-)') else writeln ('No! :-(');
readln;
end.
Compiler output:
Compile Project, Target: C:\pasPRJ\AnonymousProcs\project1.exe: Exit code 1, Errors: 1, Hints: 2
Hint: Start of reading config file C:\fpc\fpc\bin\x86_64-win64\fpc.cfg
Hint: End of reading config file C:\fpc\fpc\bin\x86_64-win64\fpc.cfg
Verbose: Free Pascal Compiler version 3.3.1-12746-g9bfb45dc05 [2023/06/10] for x86_64
Verbose: Copyright (c) 1993-2023 by Florian Klaempfl and others
Verbose: Target OS: Win64 for x64
Verbose: Compiling project1.lpr
Progress: 2 233/768 Kb Used
project1.lpr(39,9) Error: Internal error 2011010304
Verbose: C:\fpc\fpc\bin\x86_64-win64\ppcx64.exe returned an error exitcode
When compiled in Delphi, the program prints:
Outer function was called
now calling f_inner
Hello World!
Now the context of "main()" is lost. Can we still print the string "str"?
Hello World!
Yes! :-)