* Simple example on interfaces @ 2021-01-25 16:08 Mario Blunk 2021-01-25 16:41 ` Dmitry A. Kazakov ` (2 more replies) 0 siblings, 3 replies; 28+ messages in thread From: Mario Blunk @ 2021-01-25 16:08 UTC (permalink / raw) I'm trying to solve a problem of multiple inheritance. It seems to me that an interface could be the solution although the interface is still a mystery for me. This is the example code: https://github.com/Blunk-electronic/ada_training/blob/master/src/interfaces_1/interfaces_1.adb The problem to solve is: Type_A2 and type_B1 shall have the property p2 which is type_enum. The anchestors of type_A2 and type_B1 must not have this property. Both type_A2 and type_B1 shall inherit p2 from type_C so that p2 must not be written all over again. Would an interface be the solution ? Thanks for your help. ^ permalink raw reply [flat|nested] 28+ messages in thread
* Re: Simple example on interfaces 2021-01-25 16:08 Simple example on interfaces Mario Blunk @ 2021-01-25 16:41 ` Dmitry A. Kazakov 2021-01-25 17:51 ` Mario Blunk 2021-01-25 17:00 ` Jeffrey R. Carter 2021-01-25 19:05 ` Stephen Leake 2 siblings, 1 reply; 28+ messages in thread From: Dmitry A. Kazakov @ 2021-01-25 16:41 UTC (permalink / raw) On 2021-01-25 17:08, Mario Blunk wrote: > I'm trying to solve a problem of multiple inheritance. It seems to me that an interface could be the solution although the interface is still a mystery for me. > > This is the example code: > https://github.com/Blunk-electronic/ada_training/blob/master/src/interfaces_1/interfaces_1.adb > > The problem to solve is: > Type_A2 and type_B1 shall have the property p2 which is type_enum. The anchestors of type_A2 and type_B1 must not have this property. > Both type_A2 and type_B1 shall inherit p2 from type_C so that p2 must not be written all over again. Would an interface be the solution ? You must define "property." What is it? In your code these types have p2 already. Is this static polymorphism not enough? Do you need A2 and B1 in a class having p2, with polymorphic objects of the class? Then that would indeed be an interface. Now, there is no full multiple inheritance in Ada, if p2 must be a component, you are out of luck. You have only one shot and you have spent it on p0 in the type Base. But if p2 could be a function or a getter/setter pair then you can do this: type P2_Interface is interface; function P2 (Object : P2_Interface) return Enum is abstract; type A2 is new A1 and P2_Interface with private; overriding function P2 (Object : A2) return Enum; type B1 is new Base and P2_Interface with private; overriding function P2 (Object : B1) return Enum; (I removed annoying "type_" prefix from all types) -- Regards, Dmitry A. Kazakov http://www.dmitry-kazakov.de ^ permalink raw reply [flat|nested] 28+ messages in thread
* Re: Simple example on interfaces 2021-01-25 16:41 ` Dmitry A. Kazakov @ 2021-01-25 17:51 ` Mario Blunk 2021-01-25 22:06 ` Dmitry A. Kazakov 2021-01-26 10:02 ` Stephen Leake 0 siblings, 2 replies; 28+ messages in thread From: Mario Blunk @ 2021-01-25 17:51 UTC (permalink / raw) > You must define "property." What is it? With "property" I mean the selectors like p0, p1 or p2. > In your code these types have p2 > already. Is this static polymorphism not enough? It seems so. Suppose there would be more types like C1, D1, ..., each of which derived from type_base, then I don't want to define p2 over and over. > Do you need A2 and B1 > in a class having p2, with polymorphic objects of the class? Then that > would indeed be an interface. How would that look like ? > Now, there is no full multiple inheritance in Ada, if p2 must be a > component, you are out of luck. You have only one shot and you have > spent it on p0 in the type Base. That is forbidden as far as the final application is concerned. The example I posted here is a simplification of a more complex scenario. > But if p2 could be a function or a getter/setter pair then you can do this: > > type P2_Interface is interface; > function P2 (Object : P2_Interface) return Enum is abstract; > > type A2 is new A1 and P2_Interface with private; > overriding function P2 (Object : A2) return Enum; > > type B1 is new Base and P2_Interface with private; > overriding function P2 (Object : B1) return Enum; I need to digest that... I know an interface can not have a selector, just abstract functions. > (I removed annoying "type_" prefix from all types) I got used to this notation in order to avoid confusion between a type and a variable. Not important here. ^ permalink raw reply [flat|nested] 28+ messages in thread
* Re: Simple example on interfaces 2021-01-25 17:51 ` Mario Blunk @ 2021-01-25 22:06 ` Dmitry A. Kazakov 2021-01-26 7:33 ` G.B. 2021-01-26 9:37 ` J-P. Rosen 2021-01-26 10:02 ` Stephen Leake 1 sibling, 2 replies; 28+ messages in thread From: Dmitry A. Kazakov @ 2021-01-25 22:06 UTC (permalink / raw) On 2021-01-25 18:51, Mario Blunk wrote: > >> You must define "property." What is it? > With "property" I mean the selectors like p0, p1 or p2. They are components or else record members. >> In your code these types have p2 >> already. Is this static polymorphism not enough? > It seems so. Suppose there would be more types like C1, D1, ..., each of which derived from type_base, then > I don't want to define p2 over and over. There are two different things: 1. interface of a type (in general sense) 2. an implementation of Ada interface is a type that has interface and no implementation. [It is a silly idea inherited from Java.] So: - if "define" applies to #1, then yes, you can inherit from Ada interface and thus you do not need to "define" inherited primitive operations like P2 again. - if "define" applies to #2, then no, you cannot inherit implementation from Ada interface because it can have none. The first non-abstract type inheriting from an Ada interface must implement its interface in full. The types derived from it will inherit that implementation. But each sibling as A2 and B1 must implement the interface anew. >> Do you need A2 and B1 >> in a class having p2, with polymorphic objects of the class? Then that >> would indeed be an interface. > How would that look like ? with declarations from the previous post: procedure Print_P2 (Object : P2_Interface'Class) is begin Put ("P2=" & Enum'Image (Object.P2)); end Print_P2; X : A2; Y : B1; begin Print_P2 (X); Print_P2 (Y); >> Now, there is no full multiple inheritance in Ada, if p2 must be a >> component, you are out of luck. You have only one shot and you have >> spent it on p0 in the type Base. > That is forbidden as far as the final application is concerned. The example I posted here is a simplification of a more complex scenario. There exist various dirty tricks to emulate full multiple inheritance but no universal solution. If you really need full multiple inheritance, choose the most important path of implementations and make types along it proper types. Other paths if simple, could tricked using - Min-in inheritance - Generic packages to automate implementation of interfaces - Memory pools to inject implementation Nothing of these is good. They basically work only if the depths of the secondary inheritance paths is 1. -- Regards, Dmitry A. Kazakov http://www.dmitry-kazakov.de ^ permalink raw reply [flat|nested] 28+ messages in thread
* Re: Simple example on interfaces 2021-01-25 22:06 ` Dmitry A. Kazakov @ 2021-01-26 7:33 ` G.B. 2021-01-26 8:07 ` Dmitry A. Kazakov 2021-01-26 9:37 ` J-P. Rosen 1 sibling, 1 reply; 28+ messages in thread From: G.B. @ 2021-01-26 7:33 UTC (permalink / raw) On 25.01.21 23:06, Dmitry A. Kazakov wrote: >> That is forbidden as far as the final application is concerned. The example I posted here is a simplification of a more complex scenario. > > There exist various dirty tricks to emulate full multiple inheritance but no universal solution. If you really need full multiple inheritance, choose the most important path of implementations and make types along it proper types. Other paths if simple, could tricked using > > - Min-in inheritance > - Generic packages to automate implementation of interfaces > - Memory pools to inject implementation > > Nothing of these is good. They basically work only if the depths of the secondary inheritance paths is 1. > (Mix-in inheritance?) Composition can be a good alternative, too. It can help making the type graph modular. It naturally adds separation of concerns. Is there good reason to prefer Is-A over Has-A? If all the types are related through inheritance, will refactoring become easier or harder? ^ permalink raw reply [flat|nested] 28+ messages in thread
* Re: Simple example on interfaces 2021-01-26 7:33 ` G.B. @ 2021-01-26 8:07 ` Dmitry A. Kazakov 2021-01-26 8:17 ` Mario Blunk 0 siblings, 1 reply; 28+ messages in thread From: Dmitry A. Kazakov @ 2021-01-26 8:07 UTC (permalink / raw) On 2021-01-26 08:33, G.B. wrote: > Composition can be a good alternative, too. Composition was the starting point. See the original post. > It can help making the type graph modular. By modular by mean disconnected? But the question was to make it connected by removing duplicated nodes. > It naturally adds separation of concerns. > Is there good reason to prefer Is-A over Has-A? It is not a question of preference, it either fallacy (when set in mixed with a member of) or else different interfaces, like record type interface vs. some other interface. > If all the types are related through inheritance, > will refactoring become easier or harder? You meant reuse, probably. Composition was zero re-use beyond your editor's clipboard support of cut-and-paste. As for logical relationships between types, usually such things are influenced by the problem space. The question of design to map these by language types. -- Regards, Dmitry A. Kazakov http://www.dmitry-kazakov.de ^ permalink raw reply [flat|nested] 28+ messages in thread
* Re: Simple example on interfaces 2021-01-26 8:07 ` Dmitry A. Kazakov @ 2021-01-26 8:17 ` Mario Blunk 2021-01-26 8:55 ` Dmitry A. Kazakov 0 siblings, 1 reply; 28+ messages in thread From: Mario Blunk @ 2021-01-26 8:17 UTC (permalink / raw) Dmitry, thanks for your help. I reordered things in the example. The outcome can be seen here: https://github.com/Blunk-electronic/ada_training/tree/master/src/interfaces But as you already said, p2 can not be a real record element as we can see in https://github.com/Blunk-electronic/ada_training/blob/master/src/interfaces/lib/pac_1.adb There is no source to fetch the "content" of p2 as there is no element p2. Perhaps I did not understand your approach completely. I think I should abandon the idea to solve the problem with an interface. ^ permalink raw reply [flat|nested] 28+ messages in thread
* Re: Simple example on interfaces 2021-01-26 8:17 ` Mario Blunk @ 2021-01-26 8:55 ` Dmitry A. Kazakov 0 siblings, 0 replies; 28+ messages in thread From: Dmitry A. Kazakov @ 2021-01-26 8:55 UTC (permalink / raw) On 2021-01-26 09:17, Mario Blunk wrote: > thanks for your help. I reordered things in the example. The outcome can be seen here: > https://github.com/Blunk-electronic/ada_training/tree/master/src/interfaces > > But as you already said, p2 can not be a real record element as we can see in > https://github.com/Blunk-electronic/ada_training/blob/master/src/interfaces/lib/pac_1.adb > There is no source to fetch the "content" of p2 as there is no element p2. > > Perhaps I did not understand your approach completely. You must provide an implementation for P2: type A2 is new A1 and P2_Interface with private; overriding function P2 (Object : A2) return Enum; type B1 is new Base and P2_Interface with private; overriding function P2 (Object : B1) return Enum; private type A2 is new A1 and P2_Interface with record P2_Implementation : Enum; end record; type B1 is new Base and P2_Interface with record P2_Implementation : Enum; end record; You cannot re-use this implementation. Here you re-use the interface only. There are tricks to re-use implementation as well. As I said I would not recommend them. Anyway, for example, this is how generics can be used to hang an interface on a type. generic type Victim is abstract new Base with private; package Generic_Add_P2 is type Victim_With_P2 is abstract new Victim and P2_Interface with private; overriding function P2 (Object : Victim_With_P2) return Enum; private type Victim_With_P2 is new Victim and P2_Interface with record P2_Implementation : Enum; end record; end Generic_Add_P2; package body Generic_Add_P2 is function P2 (Object : Victim_With_P2) return Enum is begin return Object.P2_Implementation; end P2; end Generic_Add_P2; package Do_A2 is new Generic_Add_P2 (A1); type A2 is new Do_A2.Victim_With_P2 with record -- other members end record; package Do_B1 is new Generic_Add_P2 (Base); type B1 is new Do_B1.Victim_With_P2 with record -- other members end record; You can extend that to have a setter as well. It might even be possible to achieve the getter/setter's syntax to X := A2.P2; A2.P2 := Low; rather than X := A2.P2; Set (A2, Low); But I am too lazy to figure it out, as it would require dozens of helper and access types. I never use this horrific new Ada 2012+ stuff. Maybe someone else might help... -- Regards, Dmitry A. Kazakov http://www.dmitry-kazakov.de ^ permalink raw reply [flat|nested] 28+ messages in thread
* Re: Simple example on interfaces 2021-01-25 22:06 ` Dmitry A. Kazakov 2021-01-26 7:33 ` G.B. @ 2021-01-26 9:37 ` J-P. Rosen 2021-01-26 10:25 ` Dmitry A. Kazakov 1 sibling, 1 reply; 28+ messages in thread From: J-P. Rosen @ 2021-01-26 9:37 UTC (permalink / raw) Le 25/01/2021 à 23:06, Dmitry A. Kazakov a écrit : > Ada interface is a type that has interface and no implementation. [It is > a silly idea inherited from Java.] > To make it look a little less silly, think of it as a promise: a type that implements an interface promises to provide a certain number of operations. Then you can define algorithms that work on any type that fulfills the promises. To me, the big benefit of interfaces is that it is NOT inheritance; you say that your type provides some operations, without needing to classify it with an is-a relationship. (I can hear screamings of pure-OO people who will not agree with me ;-) ) -- J-P. Rosen Adalog 2 rue du Docteur Lombard, 92441 Issy-les-Moulineaux CEDEX Tel: +33 1 45 29 21 52, Fax: +33 1 45 29 25 00 http://www.adalog.fr ^ permalink raw reply [flat|nested] 28+ messages in thread
* Re: Simple example on interfaces 2021-01-26 9:37 ` J-P. Rosen @ 2021-01-26 10:25 ` Dmitry A. Kazakov 2021-01-26 11:15 ` AdaMagica 0 siblings, 1 reply; 28+ messages in thread From: Dmitry A. Kazakov @ 2021-01-26 10:25 UTC (permalink / raw) On 2021-01-26 10:37, J-P. Rosen wrote: > Le 25/01/2021 à 23:06, Dmitry A. Kazakov a écrit : >> Ada interface is a type that has interface and no implementation. [It >> is a silly idea inherited from Java.] >> > To make it look a little less silly, think of it as a promise: a type > that implements an interface promises to provide a certain number of > operations. I agree. I meant that Ada 95 had that already: type Interface is abstract tagged null record; There was no need to introduce it as a separate concept. I think the real reason was laziness. Vendors did not want to implement full multiple inheritance. Adding a simple constraint on the base types looked bad and also breached privacy: type Is_It_Interface is abstract tagged private; private type Is_It_Interface is abstract tagged null record; > Then you can define algorithms that work on any type that fulfills the > promises. > > To me, the big benefit of interfaces is that it is NOT inheritance; you > say that your type provides some operations, without needing to classify > it with an is-a relationship. But you do. When you say that T provides F that in other words means T *is-a* member of a class that provides F. Interface is merely a formalization of that. > (I can hear screamings of pure-OO people who will not agree with me ;-) ) OO muddied a lot of water. To me things are quite pragmatic. How do I spell in the language the fact that Long_Integer is an integer? If Integer is an integer and Long_Integer is an integer can I write a program that works on integers? Can it be the *same* program for each instance of? Simple, natural questions. -- Regards, Dmitry A. Kazakov http://www.dmitry-kazakov.de ^ permalink raw reply [flat|nested] 28+ messages in thread
* Re: Simple example on interfaces 2021-01-26 10:25 ` Dmitry A. Kazakov @ 2021-01-26 11:15 ` AdaMagica 2021-01-26 11:53 ` Dmitry A. Kazakov 0 siblings, 1 reply; 28+ messages in thread From: AdaMagica @ 2021-01-26 11:15 UTC (permalink / raw) Dmitry A. Kazakov schrieb am Dienstag, 26. Januar 2021 um 11:25:41 UTC+1: > How do I > spell in the language the fact that Long_Integer is an integer? If > Integer is an integer and Long_Integer is an integer can I write a > program that works on integers? Can it be the *same* program for each > instance of? Simple, natural questions. This is what generics are for (since Ada 83). ^ permalink raw reply [flat|nested] 28+ messages in thread
* Re: Simple example on interfaces 2021-01-26 11:15 ` AdaMagica @ 2021-01-26 11:53 ` Dmitry A. Kazakov 2021-01-26 16:46 ` AdaMagica 0 siblings, 1 reply; 28+ messages in thread From: Dmitry A. Kazakov @ 2021-01-26 11:53 UTC (permalink / raw) On 2021-01-26 12:15, AdaMagica wrote: > Dmitry A. Kazakov schrieb am Dienstag, 26. Januar 2021 um 11:25:41 UTC+1: >> How do I >> spell in the language the fact that Long_Integer is an integer? If >> Integer is an integer and Long_Integer is an integer can I write a >> program that works on integers? Can it be the *same* program for each >> instance of? Simple, natural questions. > > This is what generics are for (since Ada 83). Right, generics is a form of polymorphism (static one). Generics have interfaces and these form classes. The problem with generics (static polymorphism which also includes overloading) is that they answer no to the last question. There cannot be same program because there is no class-wide (polymorphic) objects from the generics' class. P.S. Comparing generics to overloading, generics offer some re-use, and some degree of formalization at the cost of producing huge mess, while overloading does none. -- Regards, Dmitry A. Kazakov http://www.dmitry-kazakov.de ^ permalink raw reply [flat|nested] 28+ messages in thread
* Re: Simple example on interfaces 2021-01-26 11:53 ` Dmitry A. Kazakov @ 2021-01-26 16:46 ` AdaMagica 2021-01-26 19:44 ` Dmitry A. Kazakov 0 siblings, 1 reply; 28+ messages in thread From: AdaMagica @ 2021-01-26 16:46 UTC (permalink / raw) Dmitry A. Kazakov schrieb am Dienstag, 26. Januar 2021 um 12:53:25 UTC+1: > The problem with generics (static polymorphism which also includes > overloading) is that they answer no to the last question. There cannot > be same program because there is no class-wide (polymorphic) objects > from the generics' class. universal_integer being something like class of all integers, this would be: generic type T is range <>; procedure F (X: T); is replaced by the classwide procedure F (X: universal_integer); -- not Ada universal_integer is anonymous and doesn't have any operations (except automatic conversion). > P.S. Comparing generics to overloading, generics offer some re-use, and > some degree of formalization at the cost of producing huge mess, while > overloading does none. I know you don't like generics. I do not see a huge mess. ^ permalink raw reply [flat|nested] 28+ messages in thread
* Re: Simple example on interfaces 2021-01-26 16:46 ` AdaMagica @ 2021-01-26 19:44 ` Dmitry A. Kazakov 2021-01-26 20:04 ` Shark8 2021-01-27 3:09 ` Randy Brukardt 0 siblings, 2 replies; 28+ messages in thread From: Dmitry A. Kazakov @ 2021-01-26 19:44 UTC (permalink / raw) On 2021-01-26 17:46, AdaMagica wrote: > Dmitry A. Kazakov schrieb am Dienstag, 26. Januar 2021 um 12:53:25 UTC+1: >> The problem with generics (static polymorphism which also includes >> overloading) is that they answer no to the last question. There cannot >> be same program because there is no class-wide (polymorphic) objects >> from the generics' class. > > universal_integer being something like class of all integers, this would be: Maybe class, maybe parent (cloned upon type X is new Y constructs). > generic > type T is range <>; > procedure F (X: T); > > is replaced by the classwide > > procedure F (X: universal_integer); -- not Ada Or, maybe procedure F (X: universal_integer'Class); -- not Ada > universal_integer is anonymous and doesn't have any operations (except automatic conversion). Yes. In a never ending discussion with Randy I insist that this stuff should be made explicit, available for any types. >> P.S. Comparing generics to overloading, generics offer some re-use, and >> some degree of formalization at the cost of producing huge mess, while >> overloading does none. > > I know you don't like generics. I do not see a huge mess. When something goes wrong it is almost impossible to figure what. Contracts are mostly implicit. They are not enforced upon compilation. Instantiation errors nobody can really predict. On top of that is uncontrollable name space pollution. -- Regards, Dmitry A. Kazakov http://www.dmitry-kazakov.de ^ permalink raw reply [flat|nested] 28+ messages in thread
* Re: Simple example on interfaces 2021-01-26 19:44 ` Dmitry A. Kazakov @ 2021-01-26 20:04 ` Shark8 2021-01-26 21:34 ` Dmitry A. Kazakov 2021-01-27 3:11 ` Randy Brukardt 2021-01-27 3:09 ` Randy Brukardt 1 sibling, 2 replies; 28+ messages in thread From: Shark8 @ 2021-01-26 20:04 UTC (permalink / raw) On Tuesday, January 26, 2021 at 12:44:45 PM UTC-7, Dmitry A. Kazakov wrote: > Instantiation errors nobody can really predict. On top of that is > uncontrollable name space pollution. I submitted an AI that solves a lot of the pollution: http://www.ada-auth.org/cgi-bin/cvsweb.cgi/ai12s/ai12-0268-1.txt?rev=1.3&raw=N ^ permalink raw reply [flat|nested] 28+ messages in thread
* Re: Simple example on interfaces 2021-01-26 20:04 ` Shark8 @ 2021-01-26 21:34 ` Dmitry A. Kazakov 2021-01-27 3:11 ` Randy Brukardt 1 sibling, 0 replies; 28+ messages in thread From: Dmitry A. Kazakov @ 2021-01-26 21:34 UTC (permalink / raw) On 2021-01-26 21:04, Shark8 wrote: > On Tuesday, January 26, 2021 at 12:44:45 PM UTC-7, Dmitry A. Kazakov wrote: >> Instantiation errors nobody can really predict. On top of that is >> uncontrollable name space pollution. > I submitted an AI that solves a lot of the pollution: > http://www.ada-auth.org/cgi-bin/cvsweb.cgi/ai12s/ai12-0268-1.txt?rev=1.3&raw=N Well, it would have only limited use. The case you present is rather solved by using child generics as they "inherit" parameters. So generic package Generic_Swap.Generic_Stack is And here we come to the real-world problem. Generic packages and their formal parameters are organized in a directed acyclic graph like: A D / \ /| B C | \ / | E | \ / F rather than a tree. You want to instantiate the whole graph in a single shot. You do not want to manually specify constraints on generic formal parameters when some of them travel by several paths as D into F. BTW, observe similarity with diamond/rhombus MI. That MI has some problems generics do not have is a big lie. But in my view generics are beyond salvation. The idea is inherently weakly typed. Ada's generic contracts are too loose to be safe and too rigid for usability of C++ templates. -- Regards, Dmitry A. Kazakov http://www.dmitry-kazakov.de ^ permalink raw reply [flat|nested] 28+ messages in thread
* Re: Simple example on interfaces 2021-01-26 20:04 ` Shark8 2021-01-26 21:34 ` Dmitry A. Kazakov @ 2021-01-27 3:11 ` Randy Brukardt 2021-01-27 22:51 ` Shark8 1 sibling, 1 reply; 28+ messages in thread From: Randy Brukardt @ 2021-01-27 3:11 UTC (permalink / raw) "Shark8" <onewingedshark@gmail.com> wrote in message news:d2ad937c-7b15-4766-aa88-c0a9ce474f0bn@googlegroups.com... > On Tuesday, January 26, 2021 at 12:44:45 PM UTC-7, Dmitry A. Kazakov > wrote: >> Instantiation errors nobody can really predict. On top of that is >> uncontrollable name space pollution. > I submitted an AI that solves a lot of the pollution: > http://www.ada-auth.org/cgi-bin/cvsweb.cgi/ai12s/ai12-0268-1.txt?rev=1.3&raw=N Whatever happened to your ARG participation, anyway? You just sort of disappeared... Randy. ^ permalink raw reply [flat|nested] 28+ messages in thread
* Re: Simple example on interfaces 2021-01-27 3:11 ` Randy Brukardt @ 2021-01-27 22:51 ` Shark8 2021-01-30 8:33 ` Randy Brukardt 0 siblings, 1 reply; 28+ messages in thread From: Shark8 @ 2021-01-27 22:51 UTC (permalink / raw) On Tuesday, January 26, 2021 at 8:11:14 PM UTC-7, Randy Brukardt wrote: > "Shark8" wrote in message > > I submitted an AI that solves a lot of the pollution: > > http://www.ada-auth.org/cgi-bin/cvsweb.cgi/ai12s/ai12-0268-1.txt?rev=1.3&raw=N > Whatever happened to your ARG participation, anyway? You just sort of > disappeared... 2020 was *not* a good year for me; after being holed up on-site for 8 months and seeing less than a dozen people I found the meaning of "cabin fever" -- I'm just glad I didn't get back to my 2015–17 levels of depression. I think I have to re-type what I had on the AI that 0268-1 was rolled into, but I had some ideas for allowing the automatic-instantiation to have a name generated by it's location. If I can remember to bring my wallet into work tomorrow, I'll give you a call and place an order for a personal copy of Janus/Ada. ^ permalink raw reply [flat|nested] 28+ messages in thread
* Re: Simple example on interfaces 2021-01-27 22:51 ` Shark8 @ 2021-01-30 8:33 ` Randy Brukardt 0 siblings, 0 replies; 28+ messages in thread From: Randy Brukardt @ 2021-01-30 8:33 UTC (permalink / raw) "Shark8" <onewingedshark@gmail.com> wrote in message news:f2bf8a63-4539-4c1e-a433-6556dcd642bbn@googlegroups.com... ... >If I can remember to bring my wallet into work tomorrow, I'll give you a >call >and place an order for a personal copy of Janus/Ada. I've been working at home as much as possible during the pandemic, so I didn't see this or get your messages until now (I'm still coming into the office to do the weekly backups on Friday evenings). I'll try to get back to you on Monday. Randy. ^ permalink raw reply [flat|nested] 28+ messages in thread
* Re: Simple example on interfaces 2021-01-26 19:44 ` Dmitry A. Kazakov 2021-01-26 20:04 ` Shark8 @ 2021-01-27 3:09 ` Randy Brukardt 2021-01-27 8:05 ` Dmitry A. Kazakov 1 sibling, 1 reply; 28+ messages in thread From: Randy Brukardt @ 2021-01-27 3:09 UTC (permalink / raw) "Dmitry A. Kazakov" <mailbox@dmitry-kazakov.de> wrote in message news:ruprf8$1h6q$1@gioia.aioe.org... ... >> universal_integer is anonymous and doesn't have any operations (except >> automatic conversion). > > Yes. In a never ending discussion with Randy I insist that this stuff > should be made explicit, available for any types. As I've often said, for a new language that would certainly be a good idea. For Ada, reproducing all of the quirks of Ada would lead to an inpentrable mess. And not reproducing them would break a lot of code (and more importantly, no one could tell if their code would be broken and in extreme cases, wouldn't even know as the code would silently change meaning). As far as full multiple inheritance being too expensive to implement, I tend to think that is true for interfaces as well. :-) As always, the question is whether one wants fast code or just something that works. Full multiple inheritance certainly can be implemented by converting all selectors to Getter/Setter pairs and dispatching on every use. But that's pretty expensive for accessing an integer component. Of course, most of the time it won't matter (Janus/Ada does something like this for shared generics, and I have yet to have someone complain about performance of generic code). But there will be cases where it does matter, and this is a distributed overhead -- it applies to all types whether or not you use it (because someone could extend this type in some future unit not even written yet). Randy. ^ permalink raw reply [flat|nested] 28+ messages in thread
* Re: Simple example on interfaces 2021-01-27 3:09 ` Randy Brukardt @ 2021-01-27 8:05 ` Dmitry A. Kazakov 0 siblings, 0 replies; 28+ messages in thread From: Dmitry A. Kazakov @ 2021-01-27 8:05 UTC (permalink / raw) On 2021-01-27 04:09, Randy Brukardt wrote: > "Dmitry A. Kazakov" <mailbox@dmitry-kazakov.de> wrote in message > news:ruprf8$1h6q$1@gioia.aioe.org... > ... >>> universal_integer is anonymous and doesn't have any operations (except >>> automatic conversion). >> >> Yes. In a never ending discussion with Randy I insist that this stuff >> should be made explicit, available for any types. > > As I've often said, for a new language that would certainly be a good idea. > For Ada, reproducing all of the quirks of Ada would lead to an inpentrable > mess. And not reproducing them would break a lot of code (and more > importantly, no one could tell if their code would be broken and in extreme > cases, wouldn't even know as the code would silently change meaning). Universal_Integer is already implemented in all existing compilers. > As far as full multiple inheritance being too expensive to implement, I tend > to think that is true for interfaces as well. :-) As always, the question is > whether one wants fast code or just something that works. Full multiple > inheritance certainly can be implemented by converting all selectors to > Getter/Setter pairs and dispatching on every use. But that's pretty > expensive for accessing an integer component. Same. All this is already there and implemented. The question is why is it not formalized in the language? Consider this Ada 83: Jagged : array (1..100) of String; This is valid construct though not allowed (someone like you said it would be too expensive to implement). OK, do not implement it, but at least allow to spell the concept of an array of strings! What you say is that I cannot have an array of integers because arrays of strings is so useless, dangerous and mess, would require to design a new language etc. I did not asked arrays of strings, so far... (:-)) -- Regards, Dmitry A. Kazakov http://www.dmitry-kazakov.de ^ permalink raw reply [flat|nested] 28+ messages in thread
* Re: Simple example on interfaces 2021-01-25 17:51 ` Mario Blunk 2021-01-25 22:06 ` Dmitry A. Kazakov @ 2021-01-26 10:02 ` Stephen Leake 1 sibling, 0 replies; 28+ messages in thread From: Stephen Leake @ 2021-01-26 10:02 UTC (permalink / raw) Mario Blunk <marioblunk.alere@gmail.com> writes: >> (I removed annoying "type_" prefix from all types) > I got used to this notation in order to avoid confusion between a type > and a variable. Not important here. Another way to solve this problem is to prefix the package name when necessary. -- -- Stephe ^ permalink raw reply [flat|nested] 28+ messages in thread
* Re: Simple example on interfaces 2021-01-25 16:08 Simple example on interfaces Mario Blunk 2021-01-25 16:41 ` Dmitry A. Kazakov @ 2021-01-25 17:00 ` Jeffrey R. Carter 2021-01-27 1:48 ` philip...@gmail.com 2021-01-27 3:36 ` Randy Brukardt 2021-01-25 19:05 ` Stephen Leake 2 siblings, 2 replies; 28+ messages in thread From: Jeffrey R. Carter @ 2021-01-25 17:00 UTC (permalink / raw) On 1/25/21 5:08 PM, Mario Blunk wrote: > I'm trying to solve a problem of multiple inheritance. It seems to me that an interface could be the solution although the interface is still a mystery for me. "IMHO, Interfaces are worthless." Randy Brukardt -- Jeff Carter "You cheesy lot of second-hand electric donkey-bottom biters." Monty Python & the Holy Grail 14 ^ permalink raw reply [flat|nested] 28+ messages in thread
* Re: Simple example on interfaces 2021-01-25 17:00 ` Jeffrey R. Carter @ 2021-01-27 1:48 ` philip...@gmail.com 2021-01-27 8:06 ` Dmitry A. Kazakov 2021-01-27 3:36 ` Randy Brukardt 1 sibling, 1 reply; 28+ messages in thread From: philip...@gmail.com @ 2021-01-27 1:48 UTC (permalink / raw) > "IMHO, Interfaces are worthless." I find interfaces to be extremely valuable for abstracting I/O devices. For example in my Linux Simple I/O Library, there is code equivalent to the following (the actual code is different, as I sucked a lot of common boilerplate for I/O device interfaces into a generic package that is instantiated for each data item type): package GPIO is type Direction is (Input, Output); type PinInterface is interface; type Pin is access all PinInterface'Class; procedure Put(Self : PinInterface; state : Boolean); function Get(Self : PinInterface) return Boolean; end GPIO; I've probably defined a dozen packages that implement GPIO pins using everything from Linux kernel services to web servers. Every one of them contains a function like this: function Create(...) return GPIO.Pin; This allows code like the following: GPIO1 : GPIO.Pin := GPIO.libsimpleio.Create(RaspberryPi.GPIO18, GPIO.Output); GPIO2 : GPIO.Pin := GPIO.HTTP.Create("http://foo.munts.net", 5, GPIO.Output); GPIO3 : GPIO.Pin := GPIO.RemoteIO.Create(server, 7, GPIO.Output); This allows GPIO pins scattered far and near throughout the known universe to be treated exactly the same, even collected into an array or container. I very seldom implement more than one interface in a type definition though, unless a single device has multiple sensors (temperature and humidity, for instance). Microsoft's .Net uses this scheme pervasively, though I originally learned it in Ada and later applied the same thinking to .Net, Free Pascal, Java, Python, and C++ (and other languages). ^ permalink raw reply [flat|nested] 28+ messages in thread
* Re: Simple example on interfaces 2021-01-27 1:48 ` philip...@gmail.com @ 2021-01-27 8:06 ` Dmitry A. Kazakov 0 siblings, 0 replies; 28+ messages in thread From: Dmitry A. Kazakov @ 2021-01-27 8:06 UTC (permalink / raw) On 2021-01-27 02:48, philip...@gmail.com wrote: >> "IMHO, Interfaces are worthless." > > I find interfaces to be extremely valuable for abstracting I/O devices. Operating systems always were OO. It is impossible to design something like interrupt handler without dispatching. Interrupts are dispatching. The question is never interfaces or not. It is how much language support I can get. -- Regards, Dmitry A. Kazakov http://www.dmitry-kazakov.de ^ permalink raw reply [flat|nested] 28+ messages in thread
* Re: Simple example on interfaces 2021-01-25 17:00 ` Jeffrey R. Carter 2021-01-27 1:48 ` philip...@gmail.com @ 2021-01-27 3:36 ` Randy Brukardt 2021-01-27 23:04 ` Shark8 1 sibling, 1 reply; 28+ messages in thread From: Randy Brukardt @ 2021-01-27 3:36 UTC (permalink / raw) "Jeffrey R. Carter" <spam.jrcarter.not@spam.not.acm.org> wrote in message news:rumtg6$j94$1@dont-email.me... > On 1/25/21 5:08 PM, Mario Blunk wrote: >> I'm trying to solve a problem of multiple inheritance. It seems to me >> that an interface could be the solution although the interface is still a >> mystery for me. > > "IMHO, Interfaces are worthless." > Randy Brukardt To qualify that a bit, they're worthless to me (and I suspect, most people). For me, at least, OOP's benefits are mainly found in implementation inheritance, which is not available for Interfaces. You have to use abstract types to get those benefits. For a single program, an interface doesn't buy anything, because it is very unlikely that you'll have more than one implementation of the interface in use. (Think the queue interface in Annex A.) So using dispatching just adds complication but no benefit; most likely you'll statically bind everything anyway. Which pretty much leaves reusuable code. Here, dispatching probably does have some benefit. But you can get similar benefits from generic units with formal derived type parameters. The problem is that interface dispatching is quite expensive (not just the indexing of single inheritance dispatching, but also some sort of lookup of the appropriate table). Whereas the generic solution does most of the binding at compile-time. It may be my optimizer guru background, but indirect calls are pretty much unoptimizable. Ergo, the cost of dispatching is even worse than it appears on the surface, given that valuable optimizations like inlining, partial evaluation (currying), and all of the things that they enable aren't possible. So if the code performance matters, ultimately the interfaces will have to go. (Of course, if it *doesn't* matter, one shouldn't be warping a design for performance reasons. But it is *hard* to get rid of interfaces that are too expensive, so I think it makes most sense to be sparing with their use.) Ultimately, I think one should only use interfaces IFF there is a clear reuse case where the substantial cost of dispatching is not a concern. For me, that is approximately never, but of course your mileage may vary. Randy. ^ permalink raw reply [flat|nested] 28+ messages in thread
* Re: Simple example on interfaces 2021-01-27 3:36 ` Randy Brukardt @ 2021-01-27 23:04 ` Shark8 0 siblings, 0 replies; 28+ messages in thread From: Shark8 @ 2021-01-27 23:04 UTC (permalink / raw) On Tuesday, January 26, 2021 at 8:36:56 PM UTC-7, Randy Brukardt wrote: > > Ultimately, I think one should only use interfaces IFF there is a clear > reuse case where the substantial cost of dispatching is not a concern. For > me, that is approximately never, but of course your mileage may vary. It makes sense to use them in the internals of the compiler. Perhaps not a single-language compiler, but certainly a multilanguage one like GCC. An argument could be made for a single-language compiler in an environment like described in the DIANA reference-manual's rationale, where the DIANA-structure was meant to be passed around to things like pretty-printers and static-analyzers and code-generators. You could make an argument that it would be useful for code-generators, too. I was contemplating using something like a hybrid of IEEE694 and 3AC last year... but that's a bit of a tangent. https://standards.ieee.org/standard/694-1985.html 3AC = Three Address Code ^ permalink raw reply [flat|nested] 28+ messages in thread
* Re: Simple example on interfaces 2021-01-25 16:08 Simple example on interfaces Mario Blunk 2021-01-25 16:41 ` Dmitry A. Kazakov 2021-01-25 17:00 ` Jeffrey R. Carter @ 2021-01-25 19:05 ` Stephen Leake 2 siblings, 0 replies; 28+ messages in thread From: Stephen Leake @ 2021-01-25 19:05 UTC (permalink / raw) Mario Blunk <marioblunk.alere@gmail.com> writes: > I'm trying to solve a problem of multiple inheritance. It seems to me > that an interface could be the solution although the interface is > still a mystery for me. > > This is the example code: > https://github.com/Blunk-electronic/ada_training/blob/master/src/interfaces_1/interfaces_1.adb An interface type cannot declare any data: see http://www.ada-auth.org/standards/2xrm/html/RM-3-9-4.html So type_c can be: type type_C is interface; and you can define subprograms for type_C, but not data. -- -- Stephe ^ permalink raw reply [flat|nested] 28+ messages in thread
end of thread, other threads:[~2021-01-30 8:33 UTC | newest] Thread overview: 28+ messages (download: mbox.gz / follow: Atom feed) -- links below jump to the message on this page -- 2021-01-25 16:08 Simple example on interfaces Mario Blunk 2021-01-25 16:41 ` Dmitry A. Kazakov 2021-01-25 17:51 ` Mario Blunk 2021-01-25 22:06 ` Dmitry A. Kazakov 2021-01-26 7:33 ` G.B. 2021-01-26 8:07 ` Dmitry A. Kazakov 2021-01-26 8:17 ` Mario Blunk 2021-01-26 8:55 ` Dmitry A. Kazakov 2021-01-26 9:37 ` J-P. Rosen 2021-01-26 10:25 ` Dmitry A. Kazakov 2021-01-26 11:15 ` AdaMagica 2021-01-26 11:53 ` Dmitry A. Kazakov 2021-01-26 16:46 ` AdaMagica 2021-01-26 19:44 ` Dmitry A. Kazakov 2021-01-26 20:04 ` Shark8 2021-01-26 21:34 ` Dmitry A. Kazakov 2021-01-27 3:11 ` Randy Brukardt 2021-01-27 22:51 ` Shark8 2021-01-30 8:33 ` Randy Brukardt 2021-01-27 3:09 ` Randy Brukardt 2021-01-27 8:05 ` Dmitry A. Kazakov 2021-01-26 10:02 ` Stephen Leake 2021-01-25 17:00 ` Jeffrey R. Carter 2021-01-27 1:48 ` philip...@gmail.com 2021-01-27 8:06 ` Dmitry A. Kazakov 2021-01-27 3:36 ` Randy Brukardt 2021-01-27 23:04 ` Shark8 2021-01-25 19:05 ` Stephen Leake
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox