Foo
Bar
Foo
Foo
Are the modeswitches already always on for $mode Delphi ?
Thanks to the development team. Will this new feature be available in the next release version of fpc?
I'm glad to see that it has finally arrived in FPC - good work! This should allow us to use several nice Delphi libraries with FPC. 8-)Not only that: FPC can do more as per PascalDragon's introductary notes...
I think you can also close the issue (https://gitlab.com/freepascal.org/fpc/source/-/issues/24481) now.
I think you can also close the issue (https://gitlab.com/freepascal.org/fpc/source/-/issues/24481) now.
I'm glad to see that it has finally arrived in FPC - good work! This should allow us to use several nice Delphi libraries with FPC. 8-)Not only that: FPC can do more as per PascalDragon's introductary notes...
I think you can also close the issue (https://gitlab.com/freepascal.org/fpc/source/-/issues/24481) now.
I have been toying with old D2009 and XE2 examples today and 90% can be made to work in minutes. Much more than I expected.
These defines can help others as well:The "warn 5036 off" is just to suppress a warning about the $capturer variable:
{$ifdef windows}{$apptype console}{$endif} {$mode delphi}{$modeswitch functionreferences}{$modeswitch anonymousfunctions} {$warn 5036 off}// "Warning: (5036) Local variable "$Capturer" does not seem to be initialized"
I suppose that will be fixed later? It does not really harm, but I sometimes like to compile with -Sew.
The warnings are on:
testanon.pas(51,1) Warning: (5036) Local variable "$Capturer" does not seem to be initialized
And on line 61 the same.
I compiled with -O4 and win64. It should be reproducible in main. With -02 there is no warning.
On linux32/64 debian the warning is also there with -O4
Any idea how to convert this to Object Pascal?
Under the assumption that the allocators only take one argument you can do it like this (this requires main due to the implicit function specialization):
QuoteUnder the assumption that the allocators only take one argument you can do it like this (this requires main due to the implicit function specialization):
Firstly I just joined the forum and I couldn't figure out how to reply by quoting selected text. Is this possible?
I just actually posted this exact same question on the FPC mail list before I saw this post. So it works with only one argument but why are arguments not allowed? The type is an undefined generic so it should work in theory and only consider the parameters when the function is specialize
For quoted reply I could copy and pasted but notice how it doesn't say who the quote was from. I expected to select some text and then hover the mouse over it and have an option to quote the selection. Pressing the quote button quotes the entire message which I think need to edit by hand.
The question was more about the undefined type and adding parameters like:
generic procedure Perform<T>(func: T); begin func(1); end;
I replied and CC'd you on the mail list also since we're both having problems getting messages. I'm using a gmail account btw because my private domain was blocked (Jonas discovered this some years ago) but I think that's our problem. Other users reported this also so maybe Gmail is the culprit for them also.
Really nice feature!
Please forgive my ignorance, but how are function references superior to
type TPoint = record X : double; Y : double; end; TDistanceFunc = function(p, q: TPoint): double;
Please forgive my ignorance, but how are function references superior to
type TPoint = record X : double; Y : double; end; TDistanceFunc = function(p, q: TPoint): double;
To give a more practical example about this, with such a feature you can generalize partial function application which can be used to specialize functions:
program Project1; {$mode objfpc}{$H+} {$modeswitch functionreferences} {$modeswitch anonymousfunctions} uses SysUtils; type generic TBinaryProcedure<TParam1, TParam2> = reference to procedure(const A: TParam1; const B: TParam2); generic TUnaryProcedure<TParam1> = reference to procedure(const A: TParam1); generic function Partial<TParam1, TParam2>(Func: specialize TBinaryProcedure<TParam1, TParam2>; const AValue: TParam1): specialize TUnaryProcedure<TParam2>; begin Result := procedure(const AParam: TParam2) begin Func(AValue, AParam); end; end; procedure LogToFile(const AFile: THandle; const AMessage: String); var LogMessage: String; begin LogMessage := '[%s] %s%s'.Format([DateTimeToStr(Now), AMessage, LineEnding]); FileWrite(AFile, LogMessage[1], LogMessage.Length); end; var Log: specialize TUnaryProcedure<String>; fl: THandle; begin // Log to consone out Log := specialize Partial<THandle, String>(@LogToFile, StdOutputHandle); Log('Console Log'); // Log to console error Log := specialize Partial<THandle, String>(@LogToFile, StdErrorHandle); Log('Error Log'); // Log to file fl := FileOpen('log.txt', fmOpenWrite); Log := specialize Partial<THandle, String>(@LogToFile, fl); Log('File Log'); ReadLn; end.
Weird.This is the partial application pattern, that is used in function programming languages (https://wiki.haskell.org/Partial_application). You can see it as a generalization of OOP methods.
I suppose that is the result of the effort for achieving a partial specialization overcoming limitation of the current generics in FPC, considering this (https://forum.lazarus.freepascal.org/index.php/topic,45818.msg325801.html#msg325801) and this (https://forum.lazarus.freepascal.org/index.php/topic,58753.0.html).
I'm a big fan of the functional programming too and I'm seeing the anonymous functions handy for map/fold/filter on containers and also for async/await futures (combined with a STAX?) but I'm not so sure for the function references.Function references have a huge andvantage. So I am writing a lot of code that makes use of function pointers, for example STAX, but also my iterators library (https://github.com/Warfley/ObjPasUtils/tree/master/src/iterators), and because I don't want to restrict the user to only one kind of function pointer, I need to define everything multiple times. Look at my functypes unit (https://github.com/Warfley/ObjPasUtils/blob/master/src/functypes/functypes.pas):
Maybe they're good for replacing the current method delegates, but that would break the LCL backward compatibility, i.e. it would not happen.
I see. Not familiar with Haskell but with the scheme language (https://en.wikipedia.org/wiki/Scheme_(programming_language)) where the same pattern is used to its fullest.Weird.This is the partial application pattern, that is used in function programming languages (https://wiki.haskell.org/Partial_application).
I suppose that is the result of the effort for achieving a partial specialization overcoming limitation of the current generics in FPC, considering this (https://forum.lazarus.freepascal.org/index.php/topic,45818.msg325801.html#msg325801) and this (https://forum.lazarus.freepascal.org/index.php/topic,58753.0.html).
*snip*
*snip*I don't see it as a generalization but as an alternative way to bind code to a context. I'll admit that in the latter you'll have an internally managed context, yes.
So this is basically the generalization of OOP methods. And as such it allows to give really powerfull tools, because OOP methods are bound to classes (or objects) and inheritance. With partial application, the same principle can be extended to any type and any number of parameters.
*snip*
*snip*It reminds me of similar efforts in another language before the variadic templates were added.
Aside from that, what I find really interesting about this approach, this is possible with only very few lines of code (basically the whole logger core type, which would be some form of abstract class in OOP, is with all function definitions just 40 lines of code). OOP introduces a lot of boilerplate code. This on the other hand is very slim. So I could imagine using this for some rather small things, where previously I would have used classes with just 1 or 2 (virtual/overriden) functionsQuoteI'm a big fan of the functional programming too and I'm seeing the anonymous functions handy for map/fold/filter on containers and also for async/await futures (combined with a STAX?) but I'm not so sure for the function references.Function references have a huge andvantage. So I am writing a lot of code that makes use of function pointers, for example STAX, but also my iterators library (https://github.com/Warfley/ObjPasUtils/tree/master/src/iterators), and because I don't want to restrict the user to only one kind of function pointer, I need to define everything multiple times. Look at my functypes unit (https://github.com/Warfley/ObjPasUtils/blob/master/src/functypes/functypes.pas):
Maybe they're good for replacing the current method delegates, but that would break the LCL backward compatibility, i.e. it would not happen.
*snip*
*snip*
60 lines or so, just to basically implement something that behaves as function references (just worse, because implicit specializations don't work transitively through implicit casts). And I have this for all kinds of functions and procedures from 0 to 5 parameters, It's 600 lines of code, just to emulate what is now provided at language level (and better).
*snip*
IMHO Such an undertaking to approximate a Pascal so close to a functional language is a bit too much. But it is not that I don't appreciate it from the academic point of view.I think that it is not necessarily trying to approximate pascal to a functional language, I think this is neither wise nor actually that possible (especially as the core concepts of functional languages, algebraic type system, fully expression based programs and side effect free programming, are something that must be supported on the very core of the language).
Looks like I'm missing something obvious (I'm new to FPC) but where how do I get support for those new features? The FPC 3.2.2 doesn't seem to have it and there's no download for a newer version.
Well, safest and easy to wait for the next release.Thanks. I had a suspicion that I have to build it - now it's confirmed :)
But if you want to have it now, build it from source. Your existing 3.2.2 will build it. See https://wiki.freepascal.org/Installing_the_Free_Pascal_Compiler
Well, safest and easy to wait for the next release.Thanks. I had a suspicion that I have to build it - now it's confirmed :)
But if you want to have it now, build it from source. Your existing 3.2.2 will build it. See https://wiki.freepascal.org/Installing_the_Free_Pascal_Compiler
type TFunc = function: LongInt; var p: TProcedure; f: TFunc; n: TNotifyEvent; begin procedure(const aArg: String) begin Writeln(aArg); end('Hello World'); p := procedure begin Writeln('Foobar'); end; p(); n := procedure(aSender: TObject); begin Writeln(HexStr(Pointer(aSender)); end; n(Nil); f := function MyRes : LongInt; begin MyRes := 42; end; Writeln(f()); end.
I'm betting that the final end is simply given a list of parameters so that this anonymous function is called with them. That is, it is a declaration of an anonymous function with its simultaneous call. Correct? What is the practical use of something like this? Why would it make sense to separate a piece of code for such a function?
There isn't much use for this explicit functionality
There isn't much use for this explicit functionality
This is a workaround for not having inline variables! :D
Can possibly been used to capture variables by value:
var i,j,k:integer; ..... ...... begin .... .... procedure(i,j,k:integer) begin Queue(procedure begin Sleep(500); Writeln(i,' ',hexstr(@i),' ',j,' ',k);end); end(i,j,k); inc(i); // i is iterated BEFORE it is printed, but its old value will be printed, because it was captured by value
I did not test if this really works....
I just noticed this and anonymous functions look very useful :-).
However i tried it with my 3D engine to replace some sorting comparison callbacks with anonymous functions but i get an internal error 20020475. The code i try to compile is:
[ … ]
I use this in about a dozen places with pretty much all sort callbacks being 4-5 lines of code and it'd be neat if i could replace those with anonymous functions.
This is 67eac52f0754324e72def975fbfa4d18db27afc1 - i.e. git main from last week, but a quick look in the commit log doesn't show anything relevant so i'd expect the error to still be there.
So the outer anonymous function is essentially useless.
So the outer anonymous function is essentially useless.
Line1: p_outer was called, now calling p_inner
Line2: Hello World!
begin
end.
It gives access violation or random results, depending on the code.the type can be outside the procedure..
So the outer anonymous function is essentially useless.
I do not think so. This would be useless:This captures the variables by reference.
procedure(var i,j,k:integer) begin Queue(procedure begin Sleep(500); Writeln(i,' ',hexstr(@i),' ',j,' ',k);end); end(i,j,k); inc(i); .......
Edit: I tested in FPC:
Lazarus 2.3.0 (rev 0c96c0e3a5) FPC 3.3.1 x86_64-win64-win32/win64
Unfortunately it does not run, it raises an access violation.
The problem is line 12: Writeln(s);, if I comment it out, it runs.
When I use integer instead of String, it doesnt crash but prints an invalid number.
So there are still some fundamental problems with anonymous procedures.
Just a remark: The word anonymous is somewhat misleading. Anonymous functions do not need a name, because there is - and always must be - a named or indexed reference pointing to them.
This is my Freepascal example:
It MUST print "1", but it prints a random number.
This is my Freepascal example:
It MUST print "1", but it prints a random number.
Please report a bug for this as well.
```
procedure MyProc;
begin
end;
```
The two bugs are the same.
When I use integers it gives random results, when I use strings it gives access violations, because strings under the hood use pointers.
I assume the developers already know this, because this feature, anonymous functions, and the trunk compiler are work in progress and heavily tested.
Anyway, I believe it is too early to report errors about this feature because I would not find an end.
The problems are obvious if you compile or run nontrivial examples, which run without problems in Delphi.
As these two features are rather complicated there might still be a huge bundle of bugs lurking around so I ask you to test them to year heart's content and report found bugs to the issues on GitLab so that we can fix as many of them as possible before the next major version (which is not yet planned, so don't worry ;) ).
The following source code gives access violation at runtime in FPC.
If I modify the source and declare "f_outer" local, then it gives internal compiler error in FPC.
Both versions compile and run ok in Delphi.
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
The output of the program, when run in Delphi is:
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! :-)
Please report a bug with a small, self contained, reproducible example.
Confusion about closures' functionality and implementation is caused by not understanding their purpose. Their purpose is to define classes without actually defining classes. To do things like this:
As written earlier in the thread, that you obviously did not read, it is already available in trunk. See the first message in this thread and the 7th message in this thread.
I usually consider a feature available after it is announced.
See the first message in this thread and the 7th message in this thread.
Well, Marco already pointed out that in that case assume 3.2.2 fixes because it seems the version is back ported from trunk after all, contrary to was first anounced in this thread. I assume you agree that 3.2.2 fixes can be considered some kind of release version.
I usually consider a feature available after it is announced.
This feature is not available in 3.2.2 or 3.2.3 and won't be. Don't know how you came to that conclusion... :o
Eventually it will be released as 3.4.0, but the exact schedule for that is still unknown.
Eventually it will be released as 3.4.0, but the exact schedule for that is still unknown.
Is there a roadmap of fixes/features we're waiting on for 3.4?
Eventually it will be released as 3.4.0, but the exact schedule for that is still unknown.
Is there a roadmap of fixes/features we're waiting on for 3.4?
Perhaps this will help:
https://wiki.freepascal.org/FPC_New_Features_Trunk
Revision history shows last change in June 2023.
I'm looking for a list of things that need to be completed before the 3.4 release can be finished.
That fixes the problem.
But why? As I remember even in Delphi mode, we use @ to address a function.
Is there a mode switch to activate using @ in Delphi mode?
So why compilers does not throw any error? If @ in Delphi mode is not accepted?
We'll start release preparation for 3.4.0 when we think we've reached a suitable point.