[fpc-pascal] Re: Delphi's anonymous functions in Free Pascal
Lukasz Sokol
el.es.cr at gmail.com
Tue Oct 18 10:57:53 CEST 2011
On 17/10/2011 21:53, Andrew Pennebaker wrote:
> Does Free Pascal have anonymous functions that you can pass around,
> e.g. to a sort(compare : function, arr : array) function?
>
> If not, does anyone know any hacks to accomplish this?
>
> Cheers,
>
> Andrew Pennebaker www.yellosoft.us <http://www.yellosoft.us>
>
Yes:
//you can declare a type :
TMyFunction: function(AMyParam : TType): TOtherType;
// then implement:
function MyFunctionWithArbitraryName(AMyParam: TType): TOtherType;
begin
{do something with AMyParam}
end;
//then (or before, if the TMyFunction is in type declaration section)
function AFunctionUsingTMyFunctionAsArgument(AFunction : TMyFunction):TWhateverType;
var OtherReturn: TOtherType;
AParameterToAFunction : TType;
begin
{some code}
OtherReturn := AFunction(AParameter);
{other code}
end;
// and finally even
const MYFUNCTIONCOUNT = 1
ArrayOfTMyFunction = array[0..MYFUNCTIONCOUNT-1] of TMyFunction = (MyFunctionWithArbitraryName);
{it's a static array, so match the number of elemets}
begin
for {declared somewhere global} i := 0 to MYFUNCTIONCOUNT-1 do
WhateverReturn := AFunctionUsingTMyFunctionAsArgument(ArrayOfTMyFunction[i](MyParam));
end.
(Terms and conditions : this is invoked from /dev/mem, some syntax discrepancies may occur
as my attention moved on from this as it obviously worked)
I have written a dumb CLI interpreter this way ;) recently.
(the function table contains command name as string in a record together with the function
and the main procedure looks for the name and executes the arbitrary function when found)
TMyFunctionRecord = record
CLIName: string;
MyFunction : TMyFunction
end;
const ArrayOfCLIFunctions = array[0..CLIFUNCCOUNT-1] of TMyFunctionRecord = ({...});
var CLIFunctionToExecute : TMyFunction;
WhateverReturn : TWhateverType;
begin
for i := 0 to CLIFUNCCOUNT-1 do
if ArrayOfCLIFunctions[i].CLIName = paramstr[1] then
begin
CLIFunctionToExecute := ArrayOfCLIFunctions[i].MyFunction;
break;
end;
WhateverReturn := AFunctionUsingTMyFunctionAsArgument(CLIFunctionToExecute(MyParam));
end.
Also the 'anonymous' functions can be implemented in a separate unit which only exports the
/relevant/ ones in its interface section.
The obvious limitation / safeguard is : you must use the function of declared type to pass into
the function AFunctionUsingTMyFunctionAsArgument(AFunction : TMyFunction) and no other type;
(An obvious workaround to that is to use varargs ;) but I did not try that so I can't tell
whether that would work)
It's not much OOP in action (and may have {obvious for some //not me} performance penalties but oh well. ;)
L.
More information about the fpc-pascal
mailing list