From mboxrd@z Thu Jan 1 00:00:00 1970 X-Spam-Checker-Version: SpamAssassin 3.4.4 (2020-01-24) on polar.synack.me X-Spam-Level: X-Spam-Status: No, score=-1.9 required=5.0 tests=BAYES_00 autolearn=unavailable autolearn_force=no version=3.4.4 Path: eternal-september.org!reader01.eternal-september.org!reader02.eternal-september.org!feeder.eternal-september.org!aioe.org!.POSTED!not-for-mail From: "Dmitry A. Kazakov" Newsgroups: comp.lang.ada Subject: Re: Ada Distilled by Richard Riehle Date: Sat, 28 Jul 2018 00:16:08 +0200 Organization: Aioe.org NNTP Server Message-ID: References: <72ccb7fa-a9cb-42e6-8c29-3c06da281a45@googlegroups.com> <2212eb54-cb4a-446f-9cdf-287ef220e2c2@googlegroups.com> <1b5a58b2-65b7-4df8-80b5-03e208d249e1@googlegroups.com> NNTP-Posting-Host: IzvqdhUtDGKIMCldyDtZ+w.user.gioia.aioe.org Mime-Version: 1.0 Content-Type: text/plain; charset=utf-8; format=flowed Content-Transfer-Encoding: 7bit X-Complaints-To: abuse@aioe.org User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64; rv:52.0) Gecko/20100101 Thunderbird/52.9.1 Content-Language: en-US X-Notice: Filtered by postfilter v. 0.8.3 Xref: reader02.eternal-september.org comp.lang.ada:53993 Date: 2018-07-28T00:16:08+02:00 List-Id: On 2018-07-27 23:34, Shark8 wrote: > On Friday, July 27, 2018 at 2:07:21 PM UTC-6, Dmitry A. Kazakov wrote: >> >> Types algebra, yes. Most important type operations Ada lacks are: >> >> - ad-hoc supertypes, >> - interface inheritance, >> - full MI, >> - full MD > > Ad-hoc supertypes are, I think, a mistake. The value in SUBTYPE is that it is a singular set of restrictions [possibly null] placed upon it's "supertype". What this means is that for every SUBTYPE S there's an application of 'Base to get to the first subtype (Ada "TYPE") -- This means that the relation of TYPE/SUBTYPE can be graphed as a tree; if we introduce ad-hoc supertypes, we lose this property and now have to contend with a full many-to-many possibility TYPE-network rather than TYPE-tree. No, we don't lose anything. It is only about the order of declarations. Supertype can be declared after is child: def A def B <: A vs. def B def A :> B The topology of type relationships is same. > And I fail to see how this would be useful in-practice. (IOW, what is the real use-case? Does that use-case justify such an increase in complexity?) You could inject interfaces into existing types by creating their adoptive parents. E.g. create a descendant of Root_Stream_Type which is an ad-hoc supertype of String, and here is you streaming into/from strings. You can create classes of equivalent types, e.g. resolving messy design. Consider Unbounded_String and String. You create 1. a descendant of String which is an ad-hoc parent of Unbounded_String. Now any operation of String applies to Unbounded_String. 2. a descendant of Unbounded_String which is an ad-hoc parent of String. Now any operation of Unbounded_String applies to String. It almost always a combination of a super and subtype (in non-Ada sense): A <: ad-hoc glue type <: B To create a relation between two totally unrelated existing types A and B. > I'm in agreement with interface-inheritance, I think: IIRC, you're referring to what is essentially my idea for "abstract interfaces" whereby we could define Ada's type-system in terms of the stated hierarchy; as per this picture: https://en.wikibooks.org/wiki/Ada_Programming/Type_System#The_Type_Hierarchy -- exposing what is already fairly explicit in the LRM. Yes, you could formally describe such hierarchies because you would not inherit representations and thus could bring let differently implemented types to participate in a class and have class-wide objects of that class. > Multiple Inheritance -- I'm not sure this is a good idea at all. Looking at C++ programmers and their experiences it seems to be more trouble than it's actually worth. (Interfaces aren't so bad, but can still conflict; Delphi has the IMPLEMENTS keyword that can be used for both disambiguation as well as delegation.) ...Why do you think Ada (or its successor) should have full MI? Because it desperately needed in practical work. In my actual project it could possibly reduce the code size tenfold. MI's code reuse is emulated per interfaces passed as parameters to generics. This leads to a huge explosion of compilation units, just because I cannot inherit bodies of operations from the interfaces, which must be interfaces and cannot be abstract types. Instead of type A is abstract ... procedure FA (X : in out A); type B is abstract ... procedure FB (X : in out B); type C is new A and B ...; You must stuff "inherited" bodies into a generic to be added to whatever descendant type: type A_Interface is abstract ... procedure FA (X : in out A) is abstract; type B_Interface is abstract ... procedure FB (X : in out B) is abstract; generic type Base_Type is new A_Interface and B_Interface ... package Standing_On_The_Head is type C is new Base_Type with ...; overriding procedure FA (X : in out C); overriding procedure FB (X : in out C); end Standing_On_The_Head; If you have several lines of inheritance this gives you a ballistic combinatorial explosion of generic instances. -- Regards, Dmitry A. Kazakov http://www.dmitry-kazakov.de