[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