[fpc-pascal] Traits Proposal

Ryan Joseph genericptr at gmail.com
Wed Feb 24 16:25:10 CET 2021


Ok my summary thus far with this syntax (default interface delegation)  is that composition is possible (which is very nice) but polymorphism is not really possible so it's not exactly an alternative to multiple inheritance. Besides the complications of implementing method resolution for classes (no idea what's involved here) I would say it's a pretty low time investment to get a good chunk of what people want from multiple inheritance, although not a full fledged alternative like adding a new "trait" syntax would provide.

I want to add more examples to the GitHub page so we don't forget. The most important thing to get right is not allowing any possibility to write have ambiguous methods. Here are some common ones I could think of. Are these correct? Anything to add? I guess the compiler just gives "already declared" errors for each method with a conflict. Does the visibility of the property matter in subclasses (I assume yes)?

(****************************************************************************************)

type
  ICircle = interface
    procedure Draw;
  end;

type
  TCircle = record
    procedure Draw;
  end;

type
  TMyShape = class(ICircle)
    private
      FCircle: TCircle;
    public
      property Circle: TCircle read FCircle implements ICircle; default;
  end;

type
  TOtherShape = class(TMyShape)
    public
      // ERROR - draw is already declared
      procedure Draw;
  end;

(****************************************************************************************)

type
  TMyShape = class(ICircle)
    private
      FCircle: TCircle;
    public
      property Circle: TCircle read FCircle implements ICircle; default;

      // ERROR - Draw already declared
      procedure Draw;
  end;


(****************************************************************************************)

type
  TMyShape = class(ICircle)
    private
      FCircle: TCircle;
    public
      property Circle: TCircle read FCircle implements ICircle; default;

      // Conflict is resolved, we can now redeclare Draw and Circle.Draw will point to TMyShape.Draw instead of TCircle.Draw
      procedure ICircle.Draw = Draw;
      procedure Draw;
  end;

(****************************************************************************************)

type
  ISquare = interface
    procedure Draw;
  end;

type
  TSquare = record
    procedure Draw;
  end;

type
  TOtherShape = class(TMyShape, ISquare)
    private
      FSquare: TSquare;
    public
      // ERROR - Draw is already declared
      property Square: TSquare read FSquare implements ISquare; default;
  end;

Regards,
	Ryan Joseph



More information about the fpc-pascal mailing list