Re: [fpc-pascal] Traits Proposal
Michael Van Canneyt via fpc-pascal wrote: On Tue, 9 Feb 2021, Ryan Joseph via fpc-pascal wrote: We had talked about this some time ago and it's been rattling around in my brain so I wanted to write it down into a formal proposal where we can discuss it and hopefully agree upon a syntax. Everything is preliminary and tentative but this is a syntax which allows a "composition over inheritance" model, also known as "mix-ins" in some languages. That idea is similar to multiple inheritance except you have a concrete reference to the trait being implemented so you can resolve conflicts easily. Here's what I have so far. Please feel free to look at it and give any feedback. https://github.com/genericptr/freepascal/wiki/Traits-Proposal In general, I am charmed by this idea. I am, in whatever form it is implemented, also a proponent of the basic idea behind it, formulated on Ryan's page as: "Traits allow a "composition over inheritance" model which complement the existing single inheritance model introduced in Object Pascal. Traits are similar to multiple inheritance in languages such as C++ and Java, with the difference being an explicit reference to the class (or trait) which is being implemented." Regards, Adriaan van Os ___ fpc-pascal maillist - fpc-pascal@lists.freepascal.org https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
Re: [fpc-pascal] Traits Proposal
> On Feb 10, 2021, at 12:32 AM, Michael Van Canneyt via fpc-pascal > 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 ___ fpc-pascal maillist - fpc-pascal@lists.freepascal.org https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
Re: [fpc-pascal] Traits Proposal
On Wed, 10 Feb 2021, Ryan Joseph via fpc-pascal wrote: On Feb 10, 2021, at 12:32 AM, Michael Van Canneyt via fpc-pascal 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). I heavily object to this; We have way too much keywords as it is already. So unless there really is no other way I don't think we should introduce even more. The compiler can do the check on an object for allowed/disallowed features as soon as it is used in a 'trait'. So there really is no advantage gained by using 'trait'. The check just happens in a different place: not in the object definition, but when it is used as a trait. At that point you must check for duplicate names (and probably other things) anyway. Using 'object' has the additional advantage that you can simply use existing objects, if they fulfill any restrictions, as traits. If you impose the use of 'trait' you risk that you must define objects twice to be able to use them as a trait - once standalone, once as a trait. In Javascript you also don't need to use special classes/objects for mixins. I really do not see a good reason to introduce a new type and matching keyword. Michael. ___ fpc-pascal maillist - fpc-pascal@lists.freepascal.org https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
Re: [fpc-pascal] Traits Proposal
> On Feb 10, 2021, at 8:41 AM, Michael Van Canneyt > wrote: > > I heavily object to this; We have way too much keywords as it is already. So > unless there really is no other way I don't think we should introduce > even more. I guess the first question is whether a "trait" is a new construct or just a way to import fields/methods from a class. I like the idea of a formal new type so we can limit the scope of the feature instead of taking on the baggage of an old type like "object". I'll wait to hear from the compiler team however. Looking back at the old thread Sven said: "What I'm still missing however is a real use case. What you have presented as an example can just as easily be done with the existing delegates. And just to avoid having to cast the instance to the interface is in my opinion not enough reason for a new feature. " so the idea wasn't rejected outright but I'm not sure if this idea even had their consent. I think traits/mixins are the way of the future for OOP but that's not certain for FPC yet. For example C# is a major language which is still single-inheritance only. btw, here are some links I've gathered on how other languages support this concept: • PHP (trait): https://www.php.net/manual/en/language.oop5.traits.php • Python (mixin): https://devtut.github.io/python/mixins.html#mixin • Swift (default protocol): • https://nshipster.com/swift-default-protocol-implementations/ • http://machinethink.net/blog/mixins-and-traits-in-swift-2.0/ Regards, Ryan Joseph ___ fpc-pascal maillist - fpc-pascal@lists.freepascal.org https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
Re: [fpc-pascal] Traits Proposal
On Wed, 10 Feb 2021, Ryan Joseph via fpc-pascal wrote: On Feb 10, 2021, at 8:41 AM, Michael Van Canneyt wrote: I heavily object to this; We have way too much keywords as it is already. So unless there really is no other way I don't think we should introduce even more. I guess the first question is whether a "trait" is a new construct or just a way to import fields/methods from a class. I like the idea of a formal new type so we can limit the scope of the feature instead of taking on the baggage of an old type like "object". I'll wait to hear from the compiler team however. I don't see what baggage there is ? You said it yourself: internally it will just be an object. Just make it formally so. I also think the argument of reusing existing objects deserves consideration. Michael. ___ fpc-pascal maillist - fpc-pascal@lists.freepascal.org https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
Re: [fpc-pascal] Traits Proposal
> On Feb 10, 2021, at 9:06 AM, Michael Van Canneyt > wrote: > > You said it yourself: internally it will just be an object. Just make it > formally so. > > I also think the argument of reusing existing objects deserves consideration. Is it strange that there are extra things in the object which aren't related to the trait? You could declare destructors/constructors and maybe function modifiers that don't make sense in modern code. I don't have a strong argument I guess except it feels clean to start with a fresh slate. I'm also assuming that during development we'll find problems with how to handle feature X of objects which are conflicting somehow and it would be easier to have a new type to resolve this. I'll wait to hear from others. Still, the biggest hurdle is getting any acceptance from the compiler team. I really don't like the interface delegation pattern (from Delphi?) because it doesn't help with namespaces but as Sven suggested this should be good enough for us. Traits are easy to understand and implement but the interface delegation requires tons of boiler plate and you still need to subscript into classes instead of getting a nice unified namespace. Regards, Ryan Joseph ___ fpc-pascal maillist - fpc-pascal@lists.freepascal.org https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
Re: [fpc-pascal] Traits Proposal
On 10/02/2021 16:59, Ryan Joseph via fpc-pascal wrote: • PHP (trait): https://www.php.net/manual/en/language.oop5.traits.php 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? | ___ fpc-pascal maillist - fpc-pascal@lists.freepascal.org https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
Re: [fpc-pascal] Traits Proposal
> On Feb 10, 2021, at 10:17 AM, Martin Frb via fpc-pascal > 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 ___ fpc-pascal maillist - fpc-pascal@lists.freepascal.org https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
Re: [fpc-pascal] Traits Proposal
> On Feb 10, 2021, at 11:09 AM, Ryan Joseph 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. Regards, Ryan Joseph ___ fpc-pascal maillist - fpc-pascal@lists.freepascal.org https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
Re: [fpc-pascal] Traits Proposal
> On Feb 10, 2021, at 12:17 PM, Ryan Joseph wrote: > > 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. Also, PHP doesn't have function overloading so they need to add all these complicated conflict resolution syntaxes into their implementation. For Pascal we don't have this problem and we can simply rely on the existing rules. The only exception is when you override a method that is implemented as a trait (see the "Overrides" section in the wiki). We may not even want to allow this because it's an edge case that could be resolved by explicit references. Traits can be VERY simple if we keep it that way. Regards, Ryan Joseph ___ fpc-pascal maillist - fpc-pascal@lists.freepascal.org https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
Re: [fpc-pascal] Traits Proposal
On 10/02/2021 20:17, Ryan Joseph via fpc-pascal wrote: On Feb 10, 2021, at 11:09 AM, Ryan Joseph 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; ___ fpc-pascal maillist - fpc-pascal@lists.freepascal.org https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
Re: [fpc-pascal] Traits Proposal
> On Feb 10, 2021, at 12:40 PM, Martin Frb via fpc-pascal > wrote: > > 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; if it's the simple then just set a reference to TSomeClass inside of TSomeTrait. If the trait doesn't know anything about the implementor then you indeed need to use a dispatch table or something. Can't this be solved with existing features? btw, I don't think we should model this based on PHP, I just gave that as an example. The Swift model is much more simple and does 99% of what you want. I think that's what we should do for Pascal also. Regards, Ryan Joseph ___ fpc-pascal maillist - fpc-pascal@lists.freepascal.org https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
Re: [fpc-pascal] Traits Proposal
On 10/02/2021 21:17, Ryan Joseph via fpc-pascal wrote: On Feb 10, 2021, at 12:40 PM, Martin Frb via fpc-pascal wrote: 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; if it's the simple then just set a reference to TSomeClass inside of TSomeTrait. If the trait doesn't know anything about the implementor then you indeed need to use a dispatch table or something. Can't this be solved with existing features? btw, I don't think we should model this based on PHP, I just gave that as an example. The Swift model is much more simple and does 99% of what you want. I think that's what we should do for Pascal also. I don't have a pro/contra agenda on whether that feature should be part of the fpc trait or not. I just saw it, and thought I raise it. But also, if any option should be reserved for the future, then it matters. Because re-using "sometrait = object end" makes it less likely that an "implements" clause will be added (because "object" does already have a fully defined syntax). So I felled it might be worth being noted. -- Another option would be TSomeTrait = trait (basetrait) for (someclass_as_minimum_base_class) for (someclass) is of course optional (or rather default to TObject). So sometrait then can access self.any_trait_identifier self.someclass_ident This is a bit limiting at first, but bring in genericts generic TSomeTrait = trait (basetrait) for () Since it is a generic the compiler will not complain about unknown identifiers. It can automatically specialise, when applying a trait. Then again the "implements" clause from above could internally create a generic too. -- Btw, next question that just came up Will traits only apply to classes? or could a record / advanced record / old object also receive traits ? And one more thing that may at least be considered for design in case of future use. Consider a Trait TEmployeList = trait function FindByUnallocateWorkTime: TEmploye; end; TCompany = class end; Now the company could have Engineers and Designers. It needs to lists But the trait can obviously only be added once. Yet no-one wants to copy and paste the trait to create a 2nd verson Maybe Something like TDesignerList = trait(TEmployeList) function FindDesigerByUnallocateWorkTime: TEmploye; aliases FindByUnallocateWorkTime; end; -- Again, none of those are needed. But if they are found interesting ___ fpc-pascal maillist - fpc-pascal@lists.freepascal.org https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
Re: [fpc-pascal] Value:x:y syntax
On 2/9/2021 7:26 AM, Luis Henrique via fpc-pascal wrote: I guess one can call it optional formatting specifiers. See documentation: https://www.freepascal.org/docs-html/rtl/system/str.html I think I was lazy and didn't look in the right place, thanks Michael and Christo. This is standard Pascal real number formatting since at least the mid '70s... Ralf -- This email has been checked for viruses by Avast antivirus software. https://www.avast.com/antivirus ___ fpc-pascal maillist - fpc-pascal@lists.freepascal.org https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
Re: [fpc-pascal] Traits Proposal
> On Feb 10, 2021, at 1:51 PM, Martin Frb via fpc-pascal > wrote: > > I don't have a pro/contra agenda on whether that feature should be part of > the fpc trait or not. > I just saw it, and thought I raise it. > These issues you are raising are more related to general type safety/compatibility and probably beyond the scope of what traits should do. It also introduces lots of new concepts and syntax which make this exponentially more unlikely to get approved. The only purpose of the trait is import fields/methods into a namespace of a struct, like multiple inheritance but with references. We should keep it as simple as possible imo. > -- > Btw, next question that just came up > > Will traits only apply to classes? > > or could a record / advanced record / old object also receive traits ? > I don't see why not but nothing is settled yet. Regards, Ryan Joseph ___ fpc-pascal maillist - fpc-pascal@lists.freepascal.org https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
Re: [fpc-pascal] Traits Proposal
> On Feb 10, 2021, at 2:42 PM, Ryan Joseph wrote: > > We should keep it as simple as possible imo. It's not as elegant as other ideas we may think of but I think it's good enough to let users write boilerplate methods to resolve naming conflicts. We don't need to introduce new syntax or concepts. This is the power of traits vs multiple inheritance. We get the shared namespace like normal OOP inheritance but have full control over any conflicts that arise by mixing in traits. type TTraitA = trait procedure DoThis; end; TTraitB = trait procedure DoThis; end; type TMyClass = class private property traitA: TTraitA implements _traitA; property traitB: TTraitB implements _traitB; public // DoThis now hides traitB.DoThis like it would in normal Object Pascal procedure DoThis; end; procedure TMyClass.DoThis; begin // resolve the conflict by directly referencing the trait traitA.DoThis; end; Regards, Ryan Joseph ___ fpc-pascal maillist - fpc-pascal@lists.freepascal.org https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
Re: [fpc-pascal] Traits Proposal
> On Feb 10, 2021, at 10:17 AM, Martin Frb via fpc-pascal > wrote: > > - 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? Sorry Martin you said a lot and I missed this. :) The plan is to only export fields/methods in the public section. Regards, Ryan Joseph ___ fpc-pascal maillist - fpc-pascal@lists.freepascal.org https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
Re: [fpc-pascal] Traits Proposal
On 11/02/2021 03:07, Ryan Joseph via fpc-pascal wrote: We get the shared namespace So basically, we get the compiler to automatically create forwarder methods for us (or at least that behaviour). And that is all there is. right? In that case IIRC, it was said traits are not allowed constructors. Why? Now a constructor would and should not have a forwarding method, but that the compiler can skip. Yet, in my code, in the constructor of the TMyClass, I could add _traitA.Create even _traitA := TTraitA.Create; // if the trait was not an object, but another class. The compiler can with no doubt create the forwarder methods. And if I understand right, then that is all the compiler should do? (Not that I advertise a trait should be a class / IMHO better not) procedure TMyClass.DoThis; begin // resolve the conflict by directly referencing the trait traitA.DoThis; end; This we already can do. Write our own forwarder method. I understand it is for conflict resolution only. But see my example => as soon as you need to repeat a trait with just a change in name, you always need conflict resolution. IMHO, there are many traits that a class could need more than once. Also that only works, if a trait is included as a field. There was at least one message in this mail-thread that suggested TMyClass = class(TObject, TTraitA); The solution is on https://en.wikipedia.org/wiki/Trait_(computer_programming) /alias/: an operation that creates a new trait by adding a new name for an existing method Doing that for all methods, means having 2 identical traits, but with different names. => no conflict. ___ fpc-pascal maillist - fpc-pascal@lists.freepascal.org https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
Re: [fpc-pascal] Traits Proposal
> On Feb 10, 2021, at 7:47 PM, Martin Frb via fpc-pascal > wrote: > > In that case IIRC, it was said traits are not allowed constructors. Why? Traits are meant to be a way to import fields/methods and is based off of "object" (so it's on the stack). This is also important for using properties to alias the imported fields. It's the same with subclassing, you don't need to manually allocate the super class because it's all one structure with a shared memory space. The idea is to make a viable alternative to inheritance in the simplest way possible. > >> procedure TMyClass.DoThis; >> begin >> // resolve the conflict by directly referencing the trait >> traitA.DoThis; >> end; >> >> > This we already can do. Write our own forwarder method. > I understand it is for conflict resolution only. But see my example => as > soon as you need to repeat a trait with just a change in name, you always > need conflict resolution. > IMHO, there are many traits that a class could need more than once. I know it's not the most elegant but we need to keep this simple if there's going to be any chance of it even being considered. I will let the compiler team defer to this. Regards, Ryan Joseph ___ fpc-pascal maillist - fpc-pascal@lists.freepascal.org https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
Re: [fpc-pascal] Traits Proposal
> On Feb 10, 2021, at 7:47 PM, Martin Frb via fpc-pascal > wrote: > > I understand it is for conflict resolution only. But see my example => as > soon as you need to repeat a trait with just a change in name, you always > need conflict resolution. Please post the code snippet again. I'm not sure I understand what you're saying. The most important thing here is that we don't allow the programmer to write ambiguous code. If all else fails the code must fail to compiler, if there's any chance of any conflict whatsoever. The first reason this idea gets shot down is because people think of crazy "with" statement bugs and we need to avoid that at all costs. Regards, Ryan Joseph ___ fpc-pascal maillist - fpc-pascal@lists.freepascal.org https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
Re: [fpc-pascal] Traits Proposal
On 11/02/2021 04:20, Ryan Joseph via fpc-pascal wrote: On Feb 10, 2021, at 7:47 PM, Martin Frb via fpc-pascal wrote: I understand it is for conflict resolution only. But see my example => as soon as you need to repeat a trait with just a change in name, you always need conflict resolution. Please post the code snippet again. I'm not sure I understand what you're saying. TEmployeList = trait function FindByUnallocateWorkTime: TEmploye; // other functions/members end; TCompany = class end; Now the company could have Engineers and Designers. It needs to lists But the trait can obviously only be added once. Yet no-one wants to copy and paste the trait to create a 2nd verson Maybe Something like (aliasing / no need to copy implementation) TDesignerList = trait(TEmployeList) function FindDesigerByUnallocateWorkTime: TEmploye; aliases FindByUnallocateWorkTime; // no body /just a name replacement // and the others end; ===> TCompany = class _TraitDesigner: TDesignerList ; _TraitEngeneers: TEmployeList; end; This is clearly something that can be done later. **IF** the design is chosen to allow for it. ___ fpc-pascal maillist - fpc-pascal@lists.freepascal.org https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
Re: [fpc-pascal] Traits Proposal
> On Feb 10, 2021, at 9:05 PM, Martin Frb via fpc-pascal > wrote: > > Maybe Something like (aliasing / no need to copy implementation) > TDesignerList = trait(TEmployeList) > function FindDesigerByUnallocateWorkTime: TEmploye; aliases > FindByUnallocateWorkTime; // no body /just a name replacement > // and the others > end; I see. I used "override from" in the wiki. From my experience I don't think the compiler team will allow this since it adds news syntax and complexity so I suggest we focus on manual boilerplate functions for now. I will of course defer to them on these matters. Regards, Ryan Joseph ___ fpc-pascal maillist - fpc-pascal@lists.freepascal.org https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
Re: [fpc-pascal] Traits Proposal
On 11/02/2021 04:13, Ryan Joseph via fpc-pascal wrote: On Feb 10, 2021, at 7:47 PM, Martin Frb via fpc-pascal wrote: In that case IIRC, it was said traits are not allowed constructors. Why? Traits are meant to be a way to import fields/methods and is based off of "object" (so it's on the stack). This is also important for using properties to alias the imported fields. It's the same with subclassing, you don't need to manually allocate the super class because it's all one structure with a shared memory space. The idea is to make a viable alternative to inheritance in the simplest way possible. "don't need to manually allocate" I know, I am using old "object" for that already. So that is not new when traits come. Hence I concluded, the "trait" feature is exactly and only an automated generation of forwarder-methods (well exactly they are no longer forwarders, but imported / to the user that writes a call to them that is the same in the end) But if the above conclusion is correct (no more, no less that replacing the need for forwarders ), then it is reasonable to want the same concept for other types... I do not actually advocate it. I simple point out what would logically follow (rather than what may or may not be good) ___ fpc-pascal maillist - fpc-pascal@lists.freepascal.org https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal