Alex Rivera | Logout

Scope of anonymous methods

Asked 2009-04-29T06:41:16.593
11

One nice thing about anonymous methods is that I can use variables that are local in the calling context. Is there any reason why this does not work for out-parameters and function results?

function ReturnTwoStrings (out Str1 : String) : String;
begin
  ExecuteProcedure (procedure
                    begin
                      Str1 := 'First String';
                      Result := 'Second String';
                    end);
end;

Very artificial example of course, but I ran into some situations where this would have been useful.

When I try to compile this, the compiler complains that he "cannot capture symbols". Also, I got an internal error once when I tried to do this.

EDIT I just realized that it works for normal parameters like

... (List : TList)

Isn't that as problematic as the other cases? Who guarantees that the reference is still pointing to an alive object whenever the anonymous method is executed?

Edit
Report

1 Answer

1

I'm putting this in a separate answer because your EDIT makes your question really different.

I'll probably extend this answer later as I'm in a bit of a hurry to get to a client.

Your edit indicates you need to rethink about value types, reference types and the effect of var, out, const and no parameter marking at all.

Let's do the value types thing first.

The values of value types live on the stack and have a copy-on-assignment behaviour. (I'll try to include an example on that later).

When you have no parameter marking, the actual value passed to a method (procedure or function) will be copied to the local value of that parameter inside the method. So the method does not operate on the value passed to it, but on a copy.

When you have out, var or const, then no copy takes place: the method will refer to the actual value passed. For var, it will allow to to change that actual value, for const it will not allow that. For out, you won't be able to read the actual value, but still be able to write the actual value.

Values of reference types live on the heap, so for them it hardly matters if you have out, var, const or no parameter marking: when you change something, you change the value on the heap.

For reference types, you still get a copy when you have no parameter marking, but that is a copy of a reference that still points to the value on the heap.

This is where anonymous methods get complicated: they do a variable capture. (Barry can probably explain this even better, but I'll give it a try) In your edited case, the anonymous method will capture the local copy of the List. The anonymous method will work on that local copy, and from a compiler perspective everything is dandy.

However, the crux of your edit is the combination of 'it works for normal parameters' and 'who guarantees that the reference is still pointing to an alive object whenever the anonymous method is executed'.

answered 2009-05-01T08:22:43.930

Your Answer