[fpc-pascal] Traits Proposal

Ryan Joseph genericptr at gmail.com
Wed Feb 10 19:09:52 CET 2021



> On Feb 10, 2021, at 10:17 AM, Martin Frb via fpc-pascal <fpc-pascal at lists.freepascal.org> wrote:
> 
> The example exposes another aspect:
> 
>> trait SayWorld {
>>     public function sayHello() {
>>         parent::sayHello();
> 
> In this case the trait has access to the object/class into which it is embedded. (otherwise it could not call the inherited method of the outer class).
> 
> Is that wanted?
> (methods and fields?)
> 
> If that is wanted....
> - If it will be using the existing "object" (or advanced record), then such code is not possible.
> - One might have to think about how to declare what a trait can access? 
>    Just allow anything in the code, and attempt to resolve when the trait is embedded? IMHO maybe not?

Here's an example of how this could work. "parent" could in theory be a hidden field which the compiler sets for you when the class implementing the trait is instantiated. 

If there was no virtual/override then there would be no VMT and normal casting would work to call the base class method.

This is the area I'm not sure about yet, i.e. VMT table and overriding. There are some examples on the wiki also.

====================

type
 TSomeTrait = trait
   public
     parent: TObject;
     procedure DoThis;
 end; 

 procedure TSomeTrait .DoThis;
 begin
    // ??? here is our issue. Is this good enough to call the TBaseClass.DoThis?
    TBaseClass(parent).DoThis;
 end;

 TBaseClass = class
    procedure DoThis; virtual;
 end;

 TMyClass = class(TBaseClass)
   private
     _trait: TSomeTrait;
   public
     property someTrait: TSomeTrait implements _trait;
     // we need override because TBaseClass.DoThis is virtual.
     // The compiler can generate the body for us if we don't implement it.
     procedure DoThis; override;
     procedure AfterConstruction; override;
 end;

procedure TMyClass .AfterConstruction;
begin
  someTrait.parent := self;
end;

var
 c: TMyClass;
begin
 c := TMyClass.Create;
 c.DoThis;
end;

Regards,
	Ryan Joseph



More information about the fpc-pascal mailing list