[fpc-pascal] Traits Proposal

Ryan Joseph genericptr at gmail.com
Wed Feb 10 16:29:06 CET 2021



> On Feb 10, 2021, at 12:32 AM, Michael Van Canneyt via fpc-pascal <fpc-pascal at lists.freepascal.org> wrote:
> 
> Instead of trait you might as well use simply "object", so basically we
> could simply state that instead of an interface, you can also specify an object
> in the class definition:
> 
> 
> TMyClass = class (TParent,TMyTrait1,TMyTrait2)
> Public
>  property Trait1: TMyTrait1 read FTrait1 implements TMyTrait1;
>  property Trait2: TMyTrait2 read FTrait2 implements TMyTrait2;
> end;
> 

Here's the old thread http://free-pascal-general.1045716.n5.nabble.com/Interface-delegates-and-the-implements-property-specifier-td5734729.html#a5734741. I think we agreed on introducing "trait" because it makes it clear that they are not objects and have other limitations. Under the hood they will be objects but it's important that the new type exists so the compiler can limit certain feature, like operator overloads and constructors (see below).

What does putting them in the class hierarchy gain us? implementing duplicate traits is always going to be an error one way or another. I guess it's nice to see in the class name at least. I'll wait to hear what the compiler people think about this.

Again I think it was requested to implement traits using properties but in the simplest form all the compiler really needs to know is that 1) there is a field in the class and 2) the field if of type "trait". Even this would be good enough in theory:

type
  TMyClass = class
    FTrait: TSomeTrait;
  end;

> I also don't think you should forbid constructors; In fact I think they are
> necessary if you want to support polymorphism, because I think they create/set the VMT ?
> (the compiler people need to confirm this)

I think the VMT is created by adding virtual to a method in the class hierarchy. This is the only potentially complicated part of the feature and one I have lots of questions about (see my notes on the git page).

Constructors don't make sense because traits can never be instantiated by the programmer. There could be lifetime hooks, like AfterImplemented(parent: TObject) that the compiler calls automatically when a class is instantiated (like AfterConstruction that all Object classes can override). In fact traits should probably have a root class which is hidden, just like TObject.

> 
> The only obvious thing missing in your proposal is how this changes the RTTI of the
> objects.

Good question. My plan currently is to make trait fields be implemented via automatically generated properties simply because you get lots of free functionally.

For methods I'm going to leverage what I'm learning from implementing "implicit function specialization", which is finally getting reviewed and moving forward after more than a year of limbo. The basic idea of overloading is the same so it will be easy enough for me to hook this up. The methods don't really exist however so they won't exist in the RTTI. Overriding methods will have bodies and probably work with the RTTI.

Regards,
	Ryan Joseph



More information about the fpc-pascal mailing list