[fpc-pascal] Traits Proposal

Martin Frb lazarus at mfriebe.de
Wed Feb 10 20:40:04 CET 2021


On 10/02/2021 20:17, Ryan Joseph via fpc-pascal wrote:
>
>> On Feb 10, 2021, at 11:09 AM, Ryan Joseph <genericptr at gmail.com> wrote:
>>
>> 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;
> Thinking about this more I don't think there's even a reason for it since Object Pascal doesn't let you do stuff like this anyways. If you want to call the super class you need to use "inherited" from within the class body.  The example I posted only works if there is no virtual/override involved.
>

Its not about the keyword to be used.
Its not even about the inheritance.

In the example from https://www.php.net/manual/en/language.oop5.traits.php
The trait accesses a method defined in the class to which the trait is 
applied. (It happens to be from the base class, but that does not matter)

In Pascal that would look like

type
   TSomeTrait = trait
   public
     procedure DoTraitFoo;
   end;

   TSomeClass = class(TObject)
   private
     trait: TSomeTrait; // whatever syntax is used so that the trait is 
added
   public
     SomeVal: Integer;
     procedure DoSome;
     procedure Dispatch(var message); override;
   end;

procedure TSomeTrait.DoTraitFoo;
begin
   inherited Dispatch(nil); // from TObject
   DispatchStr('');  // from TObject
   DoSome;  // from SomeClass
   SomeVal := 1;  // if we can access methods, then why not data
end;

In the example
|  parent::sayHello();|
"parent" does not refer to the class containing the trait. "parent" = 
"inherited"

The php example tait's sayHello hides the inherited sayHello => so 
parent is needed.

So in the example this/self of the embedded trait is the entire object 
into which it is embedded.

That means also: the trait and the class must be conflictfree even for  
private variables. (except where maybe cross unit scoping hides them???)

-----------------
Leaving scoping/conflicts aside.

In Pascal TSomeTrait as it is given above can not compile, as it does 
not know what DoSome,SomeVal,Dispatch are. Not until it is embedded.
Well it could compile as a generic...

So, if a trait should have such access, then how to make sure the trait 
can compile?
Maybe:

   TSomeTrait = trait
   imports
// Those must be implement/provided by classes to which the trait is added.
     procedure DoSome;
     SomeVal : integer;
   public
     procedure DoTraitFoo;
   end;

Or (less flexible)
   TSomeTrait = trait
   extends(TSomeClass)  // can extend anything that is inherited from 
TSomeClass (i.e can access anything that a TSomeClass has)
   public
     procedure DoTraitFoo;
   end;
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.freepascal.org/pipermail/fpc-pascal/attachments/20210210/0295cf44/attachment.htm>


More information about the fpc-pascal mailing list