September 24, 2008
The post I made yesterday on anonymous methods, a new feature in Delphi 2009, stirred controversy. Here are some more thoughts
The post I made yesterday on anonymous methods, a new feature in Delphi 2009, stirred controversy. I agree on the readability comments, but you should also consider that using three nested anonymous methods was quite a stretch, not a common usage scenario.
Let's start from the beginning and examine only one step. I want to make an HTTP call and process the result. This has to be done in a thread, since I don't want it to be blocking. So whether you use anonymous methods or not you need to define a custom TThread class. Now suppose you want to use the same thread class(or its HTTP support code) for slightly different situations. You have two traditional options:
-
1. Inherit a class for each usage scenario and use the tempalte pattern: the thread execute method will call a virtual function each specific class can override. Nice, but in case the specific code is limited, creating many similar classes, mostly used only for a single object in a specific situation is far from a nice architecture.
-
2. Delphi classic alternative to inheritance is to use events. In fact, you don't inherit from TButton to override the Click method, but assign an external procedure to the event, using method pointers. Each customization is in a separate method you assign.
Method pointers and anonymous methods are not that different. In one case you can write the procedure in-place, but that is an option. For readability, you can write the code I had yesterday as a series of separate functions, each assigned to an anonymous methods pointer to be called later on. Will this be more readable? Possibly, even if (from JavaScript experience) I think it is mostly a matter of getting used to a style or another. In other words, syntax aside, the concept of an anonymous method is not far from that of a method pointer, but the fact they introduce a new lifetime model for variables can help.
This bring me to another point, why not keep using method pointer. Having to allocate memory for every invocation of an event (in case of execution of code in parallel) would be far from trivial in many case in which anonymous methods just "magically" work, As a commenter noted about my yesterday post, if you hit the button many times the nHit stack-based variable gets duplicated and capture for each anonymous method invocation, so not only if lives beyond its original stack location, but you can have multiple instances at the same time...
Would this mean each and every Delphi code would benefit from this new technology? Of course not, I think it is useful only in a fraction of cases. I remain convinced that an Ajax-like call is a nice scenario and that it will take some time for the Delphi community at large to master this new language feature.
posted by
marcocantu @ 6:11PM | 7 Comments
[0 Pending]
7 Comments
Before Anonymous Methods
I do admire you trying, but the first post has this
in the 'introduction':
<quote>The example is not artificially convoluted,
but makes sense.</quote>
In this article you state in the introduction:
<quote>but you should also consider that using three
nested anonymous methods was quite a stretch, not a
common usage scenario</quote>
Now, although this is not a formal contradiction, I
do think it's odd. Either the example is a real life,
sensible solution, or it's a stretch from a common
scenario. It's hard to believe both can be true.
I really, really try to see the point of anonymous
methods, but still I haven't seen an example that
convinces me. I would much rather have 10 subclasses
than one piece of unreadable code. To add to that:
one single override of a virtual member is hardly
ever the only reason to subclass. Most of times there
are several.
Comment by Bart Roozendaal
[http://blogs.sevensteps.com]
on September 24, 22:00
Before Anonymous Methods
Is the Delphi community beginning to become too
conservative? Ageing developer scared of learning
new "tricks"?
Do AM make code less readable? Somewhat. Generics do
it too, and objects too. Pure procedural functions
are much more readable then classes, with state in
fields "magically" available within methods without
being parameters or local variables, and oh! all
those little methods scattered around! And
properties? My god, you assign a value and code is
executed! Unreadable, unreadable! <g>
AM come very handy in scenarios such that in the
previous post, and Bauer also wrote a good post
showing how they can improve calls like
TThread.Synchronize.
Noone is forced to use the new features, although the
VCL could force the use somewhere, eventually Delphi
is moving on, at least, let's welcome some innovation!
Comment by Luigi D. Sandon on September 24, 22:08
Before Anonymous Methods
Simple example, let's implement a function to resize
the object list, i.e. make it smaller or larger if
required. To make it larger we can pass an anonymous
method that will add new elements.
Usage:
SetListLength(List, 10,
function: TObject;
begin
Result := TFoo.Create;
Result.Text := Edit1.Text;
end
);
Nice thing that TFoo is just any class, may be not
designed by us.
>>
TCreateNewElementProc = reference to function:
TObject;
procedure SetListLength(List: TObjectList; N: Integer;
CreateNewElement: TCreateNewElementProc);
begin
for I := List.Count - 1 downto N do
List.Delete(I);
for I := List.Count to N - 1 do
List.Add(CreateNewElement);
end;
--------
written from head, no check with real D2009 :)
Comment by kashmi on September 25, 03:27
Before Anonymous Methods
Marco,
Doesn't D2009 let you do achieve same thing by passing
'local' (= nested) procedures - ie, you get the
benefit of context 'capture', but without the rather
messy inline syntax.
I think this isn't possible prior to D2009 because you
can't pass the address of local procedures as a
callback - only of global procedures.
Comment by Roddy on September 25, 12:25
Before Anonymous Methods
Just want to say thanks for the usage examples. When I
heard of AnonMethods in D2009 and saw the initial code
samples from CodeGear, I asked myself, "where would I
use that?" More and diverse examples will help me get
my head around the concept quicker. Appreciate it. And
the counter-arguments, too.
Comment by Ken Knopfli on September 25, 12:26
Before Anonymous Methods
Roddy: one of the differences between anonymous
methods and nested procedures is exactly that, you
can use AM in more places where nested procedures
aren't allowed.
Comment by Luigi D. Sandon on September 25, 17:53
Before Anonymous Methods
One big difference between predefined methods and
inline defined methods is that the inline diefined
ones can access local variables of the procedure or
function that calls them. These will be kept in a
closure, so they'll exist long after the calling
function returned.
This is an advantage one should not forget, and what
distinguishes (except for syntax) inline defined
anonmeths from normal, predefined methods.
Comment by Rudy Velthuis
[http://rvelthuis.de]
on September 28, 20:45
Post Your Comment
Click
here for posting
your feedback to this blog.
There are currently 0 pending (unapproved) messages.