<div dir="ltr">Thanks for that, but is that true for all conditions. I remember reading and tinkering about with Delphi when it first introduced closures. At the time it made sense that the extra cruft and interface were needed to capture local state, but I was under the impression that the interface was only needed when a local state existed. In the case where the assigned method or procedure is not a closure an interface doesn't need to exist.<div><br></div><div>Consider the following bit of code:</div><div><br></div><div>type<br>  TMultiply = reference to function(Value: Integer): Integer;<br><br>function MultiplyFunc(Value: Integer): Integer;<br>begin<br>  Result := Value * 10;<br>end;<br><br>function MultiplyClosure(const S: string): TMultiply;<br>var<br>  I: Integer;<br>begin<br>  I := StrToInt(S);<br>  Exit(function(Value: Integer): Integer<br>  begin<br>    Result := I * Value;<br>  end);<br>end;<br><br>{ TForm1 }<br><br>function TForm1.MultiplyMethod(Value: Integer): Integer;<br>begin<br>  Result := Value * Tag;<br>end;<br><br>procedure TForm1.Button1Click(Sender: TObject);<br>var<br>  M: TMultiply;<br>begin<br>  case Tag of<br>    0: M := MultiplyFunc;<br>    1: M := MultiplyClosure('15');<br>  else<br>    M := MultiplyMethod;<br>  end;<br>  WriteLn(M(4));<br>  Tag := Tag + 1;<br>end;<br></div><div><br></div><div>In the situation of "M" being assigned a reference to MultiplyFunc no local state information needs to be captured inside MultiplyFunc. There will never be a need to create or initialize an interface for the purpose of capturing state. The underlying compiler code ought to be able to discard any code generating an interface and simply call MultiplyFunc.</div><div><br></div><div><div>In the situation of "M" being assigned a reference to MultiplyClosure the local variable "I" needs to be captured because it makes use of an anonymous function. As such, there is a need for a mechanism to capture this state. If the underlying compiler code uses a reference counted interface to accomplish this, then that is an understandable penalty because some capture mechanism is necessary.</div><div><br></div><div>In the situation of "M" being assigned a reference to MultiplyMethod again no local state information needs to be captured inside MultiplyMethod. The reference to Self is passed to the method as a hidden parameter each time it is invoked. "M" can a simple two pointer data structure (see TMethod), and no closure (or interface mechanism) is needed.</div><div><br></div><div>So in summary, some mechanism, such as a reference counted interface, is only needed when a value of type TMultiply is assigned to an anonymous function (a closure). Of course code that invokes a TMultiply would need to know when to use any of these possibilities (a function, method, or closure reference). I imagine detection of this possibility could be simply implemented as a small data structure, thereby saving a lot of overhead and or complexity in situations where TMultiply uses a closure reference infrequently:</div><div><br></div><div>TReferenceTo = record<br>  Kind: Integer; // 0 = procedure/function, 1 = method, 2 = closure<br>  case Integer of<br>    0: (Code: Pointer);<br>    1: (Method: TMethod);<br>    2: (Intf: IInterface);<br>  end; <br></div><div><br></div><div>Additional note: The most recent trunk revision of fpc from gitlab has a major bug with either</div><div><br></div><div>{$modeswitch functionreferences}</div><div>or</div><div>{$modeswitch anonymousfunctions}</div><div><br></div><div>I will follow up with more information about that bug in a different thread.</div><div></div></div></div>