[fpc-pascal] Closures (or anonymous functions)
Juha Manninen
juha.manninen at phnet.fi
Sun Jan 3 15:00:09 CET 2010
On lauantai, 2. tammikuuta 2010 17:13:40 Anthony Walter wrote:
> On Sat, Jan 2, 2010 at 5:44 AM, Paul Ishenin <webpirat at mail.ru> wrote:
> > Jonas Maebe wrote:
> >> http://edn.embarcadero.com/article/33336
> >>
> >> Note that even Delphi doesn't have them yet ("it might also turn up in
> >> Delphi in the future").
> >
> > Looks as something related to:
> > http://en.wikipedia.org/wiki/Anonymous_function#Delphi ? If so then this
> > is already implemented in delphi.
>
> Something I've really found useful in C#/.NET is lamda functions and
> capturing locals (closures). This feature really solves asynchronous
> design for me at least. If you can follow this code (note below how
> url and dimension locals are captured):
Right.
Anonymous functions are implemented in Delphi2009. The name is misleading
because the essential thing is not being nameless but to capture data at the
moment the function is defined (not when it's called). It really should be
called "closure" like other languages call it.
I remember one explanation that a closure is like a reversed object. An object
has data and then functions which can work on that data.
A closure is a function that encapsulates data itself.
It is used in functional programming languages and needs a different mindset
than traditional pascal programming. I haven't really used it.
However, some other new features make it interesting.
1. Generics containers. I found an article:
http://www.drbob42.com/examines/examinA5.htm
The first examples are stupid but Generics.Defaults is interesting. I used
Delphi2009 for a while and looked at its generics containers. It is innovative
although I didn't fully understand the code.
2. Making multithreading easier. This will be very important in future as
processors have many cores. I copy a section from this Delphi help page:
http://docs.embarcadero.com/products/rad_studio/delphiAndcpp2009/HelpUpdate2/EN/html/devcommon/anonymousmethods_xml.html
Regards,
Juha Manninen
Copied text:
---------------------------------------------------------
Using Code for a Parameter
Anonymous methods make it easier to write functions and structures
parameterized by code, not just values.
Multithreading is a good application for anonymous methods. if you want to
execute some code in parallel, you might have a parallel-for function that
looks like this:
type
TProcOfInteger = reference to procedure(x: Integer);
procedure ParallelFor(start, finish: Integer; proc: TProcOfInteger);
The ParallelFor procedure iterates a procedure over different threads.
Assuming this procedure is implemented correctly and efficiently using threads
or a thread pool, it could then be easily used to take advantage of multiple
processors:
procedure CalculateExpensiveThings;
var
results: array of Integer;
begin
SetLength(results, 100);
ParallelFor(Low(results), High(results),
procedure(i: Integer) // \
begin // \ code block
results[i] := ExpensiveCalculation(i); // / used as parameter
end // /
);
// use results
end;
Contrast this to how it would need to be done without anonymous methods:
probably a "task" class with a virtual abstract method, with a concrete
descendant for ExpensiveCalculation, and then adding all the tasks to a
queue--not nearly as natural or integrated.
Here, the "parallel-for" algorithm is the abstraction that is being
parameterized by code. In the past, a common way to implement this pattern is
with a virtual base class with one or more abstract methods; consider the
TThread class and its abstract Execute method. However, anonymous methods make
this pattern--parameterizing of algorithms and data structures using code--far
easier.
-----------------------------------------------------------
More information about the fpc-pascal
mailing list