David Heffernan 2345 Posted May 4, 2019 1 hour ago, Rudy Velthuis said: C# delegates are terribly complex, and that is why they work the way they do. Delphi has more or less lightweight implementations for procedural and method types. Good for us. So I'll repeat it: If people want the complexity of C#, then they should use C#. They really aren't complex at all to use. Which is my point. You are talking about the implementation details. If you find C# complex then that's on you. Since you declared a few comments back that you didn't really have a sound grasp of C# delegates perhaps you should become knowledgeable on the subject before acting like an expert. Just a thought. Myself, I don't find C# delegates at all complex. It would certainly be pretty convenient if you could use anon methods as event handlers, as you can trivially do in C#. I understand why you can't in Delphi and it's too late to change now. But when you write code in other languages that don't have backwards compatability constraints, it can be irritating when you come back to Delphi. Share this post Link to post
Rudy Velthuis 91 Posted May 4, 2019 (edited) 19 hours ago, David Heffernan said: David is making a good point here. If Emba were starting from scratch here, would they end up with all these different incompatible procedural types? I doubt it. Yes, I guess so (i.e, I don't doubt it). You can assign a normal procedural type and a method to a "reference to" pointer, but the latter is not really a simple type. Compared to them, procedural types and method pointers are far more lightweight. If they had used something like anonmeths for events from the start, I am sure that people would already have called for simpler types instead, like what we have now. Edited May 4, 2019 by Rudy Velthuis Share this post Link to post
Rudy Velthuis 91 Posted May 4, 2019 (edited) 2 hours ago, David Heffernan said: They really aren't complex at all to use. Which is my point. You are talking about the implementation details. If the "implementation details" make them much heavier (i.e. have much more overhead), because they require the generation of an object and an interface and the capture of local variables, then these details do matter. The current types are also easy enough to use. Yes, there is sometimes confusion about the fact you can't assign a simple prodcedure to an event, but that is it. That is is not a good reason to use all these complex types everywhere. Heck, even if a proper event method explicitly has to call a simple procedure, then that is still far less overhead than an anonmeth. Edited May 4, 2019 by Rudy Velthuis Share this post Link to post
Chris Rolliston 1 Posted May 4, 2019 By the by, this historical piece is quite an amusing read: https://web.archive.org/web/20120627043929/http://java.sun.com/docs/white/delegates.html Sun's reply to Microsoft adding delegate types to its Windows-centric version of Java (Visual J++ being Anders Hejlsberg's main project in between Delphi and C# I think...?). 1 Share this post Link to post
Rudy Velthuis 91 Posted May 4, 2019 1 hour ago, Chris Rolliston said: By the by, this historical piece is quite an amusing read: https://web.archive.org/web/20120627043929/http://java.sun.com/docs/white/delegates.html Sun's reply to Microsoft adding delegate types to its Windows-centric version of Java (Visual J++ being Anders Hejlsberg's main project in between Delphi and C# I think...?). Quote This decision was made in consultation with Borland International, who had previous experience with bound method references in Delphi Object Pascal. LOL! It seems they mean method pointers in Delphi, especially how they were used for events, and they don't want them. Ok, their decision. When I first saw events at work (a demo at CeBit 1995) I was impressed. The VCL and especially the way properties and events worked were the main reason I ordered Delphi 1 at the spot. I don't care if they are pure OOP (I actually don't see why not). Share this post Link to post
Remy Lebeau 1392 Posted May 5, 2019 11 hours ago, Rudy Velthuis said: Also, an event needs two things: an object and a code pointer. It can't do without. A plain or static function does not have those, An anonymous method does not necessarily have these either. And yet, it CAN be done with plain/static functions. I do it all the time when writing test apps that have no UIs. It is just a matter of adding an explicit Self parameter to the function, populating a TMethod record with the address of the function in the Code field and an arbitrary value in the Data field, and then assigning that TMethod to the target event via a type-cast. Share this post Link to post
uligerhardt 18 Posted May 5, 2019 9 hours ago, Remy Lebeau said: And yet, it CAN be done with plain/static functions. I do it all the time when writing test apps that have no UIs. It is just a matter of adding an explicit Self parameter to the function, populating a TMethod record with the address of the function in the Code field and an arbitrary value in the Data field, and then assigning that TMethod to the target event via a type-cast. FWIW: If I have to adapt the interface of the routine anyway I would make it into a (non-static) class method of a dummy class and stay completely inside of the type system. Share this post Link to post
Rudy Velthuis 91 Posted May 5, 2019 19 hours ago, Remy Lebeau said: And yet, it CAN be done with plain/static functions. I do it all the time when writing test apps that have no UIs. It is just a matter of adding an explicit Self parameter to the function, populating a TMethod record with the address of the function in the Code field and an arbitrary value in the Data field, and then assigning that TMethod to the target event via a type-cast. Yeah, well, you can do a lot when cheating. Share this post Link to post
Rudy Velthuis 91 Posted May 5, 2019 10 hours ago, uligerhardt said: FWIW: If I have to adapt the interface of the routine anyway I would make it into a (non-static) class method of a dummy class and stay completely inside of the type system. Yes, indeed, so would I. But you have to create and free those, to really stay inside the type system. Share this post Link to post
uligerhardt 18 Posted May 6, 2019 (edited) 10 hours ago, Rudy Velthuis said: Yes, indeed, so would I. But you have to create and free those, to really stay inside the type system. No, that's why I'm talking about class methods. You can use them like this: type TMyEventHandler = class public class procedure OnError(const AMessage: string); end; Something.OnError := TMyEventHandler.OnError; The method has to be non-static to provide the needed Self parameter. Edited May 6, 2019 by uligerhardt Typo, syntax highlighting, clarification 3 Share this post Link to post
Rudy Velthuis 91 Posted May 6, 2019 3 hours ago, uligerhardt said: No, that's why I'm talking about class methods. You can use them like this: type TMyEventHandler = class public class procedure OnError(const AMessage: string); end; Something.OnError := TMyEventHandler.OnError; The method has to be non-static to provide the needed Self parameter. Oh, Ok, I understand what you mean. Yes, that's possible. Share this post Link to post
Remy Lebeau 1392 Posted May 7, 2019 On 5/5/2019 at 2:51 AM, uligerhardt said: I would make it into a (non-static) class method of a dummy class and stay completely inside of the type system. Sometimes I do that, too. But writing a class to wrap a standalone function is not always as convenient as just using the function by itself. Share this post Link to post
Remy Lebeau 1392 Posted May 7, 2019 On 5/5/2019 at 1:30 PM, Rudy Velthuis said: Yes, indeed, so would I. But you have to create and free those, to really stay inside the type system. You don't have to create instances of the class if you use a non-static 'class' method for the event handler. It still has an implicit Self parameter, but it points to the class type instead of an object instance. Works fine with events, as long as the method doesn't need to access any members of a particular object instance. Share this post Link to post
Rudy Velthuis 91 Posted May 7, 2019 1 hour ago, Remy Lebeau said: You don't have to create instances of the class if you use a non-static 'class' method for the event handler. Yes, I got that already, thanks. Share this post Link to post