Friday, August 01, 2008

I don't get anonymous methods...

Today I watched a presentation by Adreano Lanusse and David I on Tiburon. Nothing really new was shown from the things we already know. Luckily there were a couple of exceptions showing up as my installation does from time to time :-) And I now know that showing recorded videos using Microsoft Live Meeting is not a very good idea. The upload speed of the host was just not good enough. The rest of the presentation was pretty good to watch.

During the presentation we could ask questions and mine was: what's up with anonymous methods?

We've probably all seen the example of anonymous methods shown at http://blogs.codegear.com/davidi/2008/07/23/38915.

I just don't get why you want to use anonymous methods and I'm afraid Adreano and David were not able to explain it to me.

Why wouldn't you use a private class method? Or an local procedure? I really tried but I can't think of a situation where you want to use an anonymous method.

Who can explain this to my satisfaction? Why would I be happy with those???

Bye,
Bart

12 comments:

Anonymous said...

I cannot explain it to you either and I'm too confused about them.

I too can't think about a real world usage, perhaps it will be clear if the first codings make use of them.

Cu,
Michael

Anonymous said...

With anonymous method you can use aspect oriented programming.

One example.
Sometimes you have many similar methods like this:
begin
for i:=0 to count-1 do
begin
obj:=items[i];
if obj<>nil then
begin
//Do something
end;
end;
end;
And if you do not have anonymous method then you have to repeat for loop in all methods or use calback function as parameter. But every time you need different number of parameters to callback so it look easer to duplicate logic.

With anonymous method you can do:

x(obj:TObject)=
begin
//do something with obj using
//your all
//visible here variables
end;
foreachNotNilDo(x);

Anonymous said...

Well, a friend and I asked each other the same question... and the only answer would be: to get on more spaghetti code?

Maybe is a way to come up with a functionality in your app, to later be "code-healed" with the refactoring goodies?

Roddy said...

> Why wouldn't you use a private class method? Or an local procedure?

Because you can't!

If I have this right, D2007 and before won't let you pass a local procedure or a class method as a parameter to a function - only 'regular' procedures.

That means that if your callback procedure needs to access variables in your current context, you either need to stash them in globals (yuk!) or pass them down as additional parameters (equally yuk.) So, while this isn't the most exciting new feature since buttered toast, there are circumstances where it is extremely useful.

C++Builder already has part of this, in the form of closures, which allow you to pass an object instance/method "pair", and then invoke the instance's method.

DavidI's example is so bad that I wonder if he actually understands the purpose of the concept. And, the method in his example seems far from "anonymous" - it's called "proc"!

Chris said...

Roddy: "If I have this right, D2007 and before won't let you pass a local procedure or a class method as a parameter to a function - only 'regular' procedures."

While local procedures can't indeed be passed, method pointers can be (and always could be). What made you think they can't? Event types are in fact just 'regular' method pointer types after all.

type
TCallback = procedure of object;

procedure Test(const M: TCallback);
begin
//blah
M;
end;

procedure TMyForm.DoTest;
begin
//blah
end;

procedure TMyForm.TryIt;
begin
Test(DoTest);
end;

Anonymous said...

Exactly - every single example of something that anonymous methods/closures now make possible is already achievable and so for not one example has actually been CLEARER using an anonymous approach.

It may have involved less code, but the code produced is harder to interpret - i.e. read and understand.

So you save a few seconds, maybe even minutes, creating that code, sure as eggs is eggs you are going to lose that gain when you come back to that code in weeks/months/years to come and have to figure out what the clever-clever code is code.

Code spends far more of it's life being maintained than it does being created.

For disposable code such time savers are great, but for serious use they are just storing up trouble for the future.


I'm still convinced that all we are doing with such things is inventing new "with"s for the future. Things that can naively save us some time but which exact a heavy price down the road and are best left alone.

My own additional impressions from the preview webinar are in my new blog:

http://www.deltics.co.nz/blog

(there's no content at the main site yet, only in the blog subsite)

Craig said...

"ccr," you're confusing instance methods and class methods. Roddy wrote about class methods, not instance methods. But even those are less problematic than local procs.

Anonymous said...

As far as i am aware, anonymous methods can access local variables of the calling method (which other methods cannot) and they can be passed to other code as pointers (which local procedures cannot without serious tweaking).

So, the old Turbo Pascal TCollection.ForEach or .FirstThat methods (which took a pointer to a local procedure) are possible again.

There might be other advantages that I don't know about yet.

Of course the same could have been achieved with extending local procedures and then claiming them to be equivalent to anonymous methods, but of course that wouldn't have sounded as cool.

Roddy said...

@ccr: "While local procedures can't indeed be passed, method pointers can be (and always could be). What made you think they can't?"

oops. And I did mean instance methods, not class methods.

I blame my insufficient research and a certain rustiness with Delphi - I mainly use C++Builder these days! I tried some code, but forgot the magic "of object" modifier

In which case, I'm going to struggle to find an example which can't reasonably be implemented without anonymous procedures.

DavidI's example still stinks, though... ;-)

Lars Fosdal said...

@Jolyon: I wouldn't call it disposable code, as much contextual code. The neat thing is that you can deliver that context aware code into other code that by definition is context agnostic.

Chris said...

Craig - even if Roddy really did mean class rather than instance methods, what difference does it make, since Delphi's method pointer syntax covers both? That is to say, make DoTest in my example code a class procedure and it still compiles. OK, perhaps it *shouldn't* compile, but that's a different issue... (Also, you can leave off bringing up static class methods. They *should* be acceptable as regular routines given that's all they are, but hey, who'd want to use a pointless .net source compatibility hack in the first place...?)

Craig said...

Saying the compiler permits something is different than saying it works as designed, as you note. But it's not a separate issue; the issue is exactly what you can and can't safely pass as a procedure reference. Right now, it's only instance methods, and you don't get capture. In the future, there will be more choices.

"Pascal programmers" perhaps don't see the use of this since people who haven't worked in languages with capture don't tend to think of functions as data.