Re: [fpc-pascal] Traits Proposal
> On Feb 13, 2021, at 5:09 PM, Ben Grasset via fpc-pascal > wrote: > > This seems possibly a *little* too similar to the existing Interface type in > Object Pascal, however, I *would* really like to see some kind of > functionality that basically amounts to "has the same capabilities as > Interfaces and works on records and objects too, but does NOT require any > kind of heap allocation". Not really, traits/mixins are multiple inheritance alternative. 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 13, 2021, at 12:38 PM, Sven Barth wrote: > > Right now, Ryan, your suggestion looks like a solution in search of a > problem, or a "hey, look at that feature in language X, I so must have that > in Pascal as well". Those concepts more likely then not tend to end in > problems or should be rejected. So let's first define what we're trying to > solve here: What I'm trying to solve is the dilemma of OOP where we want to extend a class but the addition does not fit cleanly into an existing hierarchy. I know we've all had this problem and we were forced to settle on injecting some base class into a hierarchy even though other classes higher up don't need this functionality. Things like class helpers and interface delegation have already been added into the language so clearly there is a need not being addressed. We've all had this problem haven't we? First off lets go summarize the differences/limitations of interface delegation (as it is now) when compared to good, old fashion normal inheritance and OOP: 1) Does not support fields, class operators, properties 2) Only supports classes so we're required to manage memory (more fragmented also which could be bad) 3) Requires you to define an interface with duplicate methods, so boilerplate code 4) Does not combine namespaces so you must cast the class as the interface or use the reference directly using dot notation (with performance implications?) inheritance is so much easier and powerful. Just add the class name () and you're good to go. That's my starting point, what ever solution should be close to as easy as what already exists in OOP. > === code begin === > > type > ITest = interface > procedure Test; > end; > > TTestImpl = record > procedure Test; > end; > > TTest = class(TObject, ITest) > private > fTest: TTestImpl; > public > property Test: TTestImpl read fTest implements ITest; default; > end; > > var > t: TTest; > begin > t := TTest.Create; > try > t.Test; // calls t.fTest.Test > finally > t.Free; > end; > end. > > === code end === > > As the compiler needs to generate corresponding thunks anyway whether it > needs to do this for a record or object is not really much more effort either. > > Whether the class needs to declare the interface in its interface clause can > be argued about. > > But all in all one can see that with a few extensions of existing features > one can easily provide a mixin-like, convenient functionality. Great, this is getting closer to inheritance. It requires a default property (which is basically what traits were anyways) and a lifting of restrictions on the object being implemented. What we solved here is: 1) Default properties merge the namespaces, which is the perhaps the most important part of OOP, that is the class is "one thing". If there is one thing to accomplish it's this. Imagine how annoying OOP would be if you you have to do "sphere.circle.shape.Draw()" because we had TSphere which inherited from TCircle and in turn inherited from TShape. 2) If we can lift the restriction of classes-only by using records/objects then we don't need to write boilerplate to alloc/free classes and our fields are now contagious in memory. Again that would be so annoying if classes made us allocate and free the super class we were inheriting from. What it leaves desired: 1) Making a dummy interface is annoying boiler plate but not a deal breaker. 2) No fields or properties although you have some solution below which will probably require some additional boiler plate. Class operators would are kind of sad to lose too but not a deal breaker. I stand by that using some concept of traits/mixins does all the stuff we want with less boiler plate but I'm happy to explore any other ideas. > > Of course this does not provide any mechanism to directly add fields, however > the compiler could in theory optimize access through property getters/setters > if they're accessed through the surrounding class instance instead of the > interface. How does this look? > > Also this does not address the point of whether these delegates are able to > access functionality of the surrounding class. In my opinion however this can > be explicitely modelled by providing the class instance through a constructor > or property or whatever. Indeed but this can be solved by more boiler plate. :) In AfterConstruction you can set references as desired. I had other ideas on this as they related to traits but that wouldn't make sense if we were using an existing type like records or classes. 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
This seems possibly a *little* too similar to the existing Interface type in Object Pascal, however, I *would* really like to see some kind of functionality that basically amounts to "has the same capabilities as Interfaces and works on records and objects too, but does NOT require any kind of heap allocation". So whether it be this, or just an improvement on the Interfaces we already have, I'd definitely personally be in favor of something that "works like Interfaces except minus the negative performance implications." On Tue, Feb 9, 2021 at 9:27 PM Ryan Joseph via fpc-pascal < fpc-pascal@lists.freepascal.org> 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 > > > > type > TSomeTrait = trait > public > field: integer; > procedure DoThis; > end; > > TMyClass = class > private > _trait: TSomeTrait; > public > property someTrait: TSomeTrait implements _trait; > end; > > var > c: TMyClass; > begin > c := TMyClass.Create; > c.DoThis; > writeln(c.field): > end; > > Regards, > Ryan Joseph > > ___ > fpc-pascal maillist - fpc-pascal@lists.freepascal.org > https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal > ___ fpc-pascal maillist - fpc-pascal@lists.freepascal.org https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
Re: [fpc-pascal] Traits Proposal
W dniu 2021-02-13 o 20:38, Sven Barth via fpc-pascal pisze: Of course this does not provide any mechanism to directly add fields, however the compiler could in theory optimize access through property getters/setters if they're accessed through the surrounding class instance instead of the interface. So the complement could be generic classes like this: type generic TTestGeneric = class(, ITest, IInterface2) private fTest: TTestImpl; public property Test: TTestImpl read fTest implements ITest; default; end; TMyTest = specialize TTestGeneric(); Something similar has already been asked: https://www.mail-archive.com/fpc-pascal@lists.freepascal.org/msg53599.html Michał. ___ fpc-pascal maillist - fpc-pascal@lists.freepascal.org https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
Re: [fpc-pascal] Traits Proposal
Am 10.02.2021 um 03:18 schrieb Ryan Joseph via fpc-pascal: 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 Time for me to tackle this topic as well. First of, I might incorporate answers to other mails of this thread here (directly or indirectly), just so you know. Right now, Ryan, your suggestion looks like a solution in search of a problem, or a "hey, look at that feature in language X, I so must have that in Pascal as well". Those concepts more likely then not tend to end in problems or should be rejected. So let's first define what we're trying to solve here: Allow the extension of a class' declaration with preexisting behavior AND state through the use of composition instead of inheritance, providing this in a convenient and possible even transparent way to the user of the class while allowing this to be implemented conveniently by the author of the class. Let's break this down and let's see whether we can naturally evolve existing language features to cover this instead of trying to shoehorn concepts of other languages for this. Obviously I know where I'm going with this, but bear with me. So the first part: "Allow the extension of a class' declaration with preexisting behavior AND state through the use of composition instead of inheritance". Obviously this is already possible in Object Pascal, namely by using the interface delegation feature. For those that aren't aware of the full capabilities of this feature, here is a small excursion (if you think you already know all there is to know, jump ahead to "end of the delegate excursion"): The interface delegation feature allows the developer of a class to redirect the implementation of a specific interface to a class or interface instance provided in the class. A simple case looks like this: === code begin === type ITest = interface procedure Test; end; TTest = class(TObject, ITest) private fTest: ITest; public property TestImpl: ITest read fTest implements ITest; end; === code end === This is however not the full ability of this feature. The property implementing this interface does not need to be an interface. It can also be a class instance and this class instance does *not* need to declare that it implements this interface. So the following is a valid interface delegation as well (Note: FPC does not support this currently, that is still an outstanding Delphi compatibility problem): === code begin === type ITest = interface procedure Test; end; TTestImpl = class procedure Test; end; TTest = class(TInterfacedObject, ITest) private fTest: TTestImpl; public property TestImpl: TTestImpl read fTest implements ITest; end; === code end === In this case the methods introduced by IInterface are implemented by TTest's parent class and ITest.Test is implemented by the TTestImpl instance. If TTestImpl inherits from e.g. TInterfacedObject then TTest does not need to inherit from TInterfacedObject itself (Note: the reference counting in relation to interface delegation and aggregation is a whole topic in and of itself and will be ignored here). One can even control which methods should be implemented by the property: === code begin === type ITest = interface procedure Test1; procedure Test2; end; TTestImpl = class procedure Test1; end; TTest = class(TInterfacedObject, ITest) private fTest: TTestImpl; public procedure ITest.Test2 = MyTest2; // name can be chosen freely, can also be "Test2" property TestImpl: TTestImpl read fTest implements ITest; procedure MyTest2; end; === code end === So far this only covered behavior, but as interfaces can also provide properties it's also possible to provide state through them (though they *have* to be implemented through explicit Getters and Setters): === code begin === type ITest = interface function GetTestProp: LongInt; procedure SetTestProp(aValue: LongInt); property TestProp: LongInt read GetTestProp write SetTestProp; end; TTestImpl = class function GetTestProp: LongInt; procedure SetTestProp(aValue: LongInt); end; TTest = class(TInterfacedObject, ITest) private fTest: TTestImpl; public property TestImpl: TTestImpl read fTest implements ITest; end; === code end === For using a delegated interface you need to cast
Re: [fpc-pascal] Windows Defender considers fp.exe a malicious program
On 13/02/2021 16:52, Ched via fpc-pascal wrote: Hello, For one software I compile with fpc, Avast always complained. But only when compiled for debugging. That exe was sent to the false positive departement, and it toke about _one mounth_ to have a corrected version of the AV. Afterwhat, he never complained even with reworked source code. I've seen a few false positives on debug info. To be fair, the AV can't really tell its not code. It could be used like a resource, later to be loaded from the file and then somehow be executed. So if debuginfo happens to look like malicious code ___ fpc-pascal maillist - fpc-pascal@lists.freepascal.org https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
Re: [fpc-pascal] Windows Defender considers fp.exe a malicious program
Hello, For one software I compile with fpc, Avast always complained. But only when compiled for debugging. That exe was sent to the false positive departement, and it toke about _one mounth_ to have a corrected version of the AV. Afterwhat, he never complained even with reworked source code. Cheers, Ched Le 13.02.21 à 12:02, Marco van de Voort via fpc-pascal a écrit : Op 2021-02-12 om 22:48 schreef James Richters via fpc-pascal: The problem I have had is when programs I compile generate a false virus detection.. sure on my own computer I can just disable that directory from the virus scanner but it becomes a problem when I release it to my customers and their virus scanners quarantine it. I have no idea how to register a legitimate program as not having a virus. I've had this issue before but managed to track down the section of code that caused it... after a completely exhaustive search. Some tips: - don't use debug builds. - sign the binary, even if just selfsigned. Provide as much context to the OS (icon and the rest in that screen). Minimalistic binaries seem to be more suspect. - use a well known installer package, and insist on using installers. Copied exes are also more suspect. - unfortunately, some wellknown Delphi libraries like Indy and Zeos sometimes trigger also. There is no real failsafe solution. It is all hedging and hoping. ___ fpc-pascal maillist - fpc-pascal@lists.freepascal.org https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
Re: [fpc-pascal] Windows Defender considers fp.exe a malicious program
On 13/02/2021 03:55, Travis Siegel via fpc-pascal wrote: that if you have any timing routines in your code, it tends to get flagged by virus scanners. No clue why, but I've run afoul of that issue more than once. I read somewhere that some viruses have a build in wait, to evade sandbox detection. AV companies let unknown exe run in a sandbox, and wait if they behave bad. Viruses evade that by being dormant for a while. ___ fpc-pascal maillist - fpc-pascal@lists.freepascal.org https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
Re: [fpc-pascal] Windows Defender considers fp.exe a malicious program
Op 2021-02-12 om 22:48 schreef James Richters via fpc-pascal: The problem I have had is when programs I compile generate a false virus detection.. sure on my own computer I can just disable that directory from the virus scanner but it becomes a problem when I release it to my customers and their virus scanners quarantine it. I have no idea how to register a legitimate program as not having a virus. I've had this issue before but managed to track down the section of code that caused it... after a completely exhaustive search. Some tips: - don't use debug builds. - sign the binary, even if just selfsigned. Provide as much context to the OS (icon and the rest in that screen). Minimalistic binaries seem to be more suspect. - use a well known installer package, and insist on using installers. Copied exes are also more suspect. - unfortunately, some wellknown Delphi libraries like Indy and Zeos sometimes trigger also. There is no real failsafe solution. It is all hedging and hoping. ___ fpc-pascal maillist - fpc-pascal@lists.freepascal.org https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
Re: [fpc-pascal] Windows Defender considers fp.exe a malicious program
> I've also noticed that if you have any timing routines in your code, it tends > to get flagged by virus scanners. No clue why, but I've run afoul of that > issue more than once. > Debugger detection? ___ fpc-pascal maillist - fpc-pascal@lists.freepascal.org https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal