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!news.eternal-september.org!news.eternal-september.org!feeder.eternal-september.org!aioe.org!.POSTED!not-for-mail From: "Dmitry A. Kazakov" Newsgroups: comp.lang.ada Subject: Re: Class-wide types algebra Date: Thu, 29 Sep 2016 10:06:07 +0200 Organization: Aioe.org NNTP Server Message-ID: References: <2837d915-12c8-4c23-8907-1d146d1abae7@googlegroups.com> NNTP-Posting-Host: vZYCW951TbFitc4GdEwQJg.user.gioia.aioe.org Mime-Version: 1.0 Content-Type: text/plain; charset=windows-1252; format=flowed Content-Transfer-Encoding: 7bit X-Complaints-To: abuse@aioe.org User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:45.0) Gecko/20100101 Thunderbird/45.3.0 X-Notice: Filtered by postfilter v. 0.8.2 Xref: news.eternal-september.org comp.lang.ada:31943 Date: 2016-09-29T10:06:07+02:00 List-Id: On 28/09/2016 22:17, Randy Brukardt wrote: > "Dmitry A. Kazakov" wrote in message > news:nsfrn6$ab7$1@gioia.aioe.org... >> On 28/09/2016 02:05, Randy Brukardt wrote: > ... >>> The problem with all forms of MI is diamond inheritance, which get much >>> worse in Ada because of our strict privacy rules. >> >> There is no any problems with diamond inheritance and visibility. > > Certainly are. If one has a hidden interface with hidden overridden > operations, and a later extension tries to add the same interface with > different overridden operations, one of two things has to happen, both bad: > (1) The interfaces are the same, so the hidden operations completely > disappear. (The new extension cannot know that they ever existed, so they > cannot be called from it.) Since the parent operation presumably depends on > those operations, trouble is certain to ensue. (When the operations aren't > overridden, then they magically become visible, which is also a problem.) > (2) The interfaces are different, so one has problems in dispatching calls > of figuring out which one to call. That way leads to madness. It is clearly #2. What you cannot see does not exist, the old good solipsism. Ada sometimes violates this principle, always for worse. There is no problem with dispatching calls so long visibility is respected: 1. Where type's primitive operations are not visible you cannot dispatch to them. 2. Where type's primitive operations are visible you cannot derive without resolving the conflict between hierarchies. From this follows that you cannot use the type in the context where hidden operations are visible! The type with an unresolved conflict (and its class-type) is invalid. Example: package P1 is type I is interface; procedure Foo (X : I) is abstract; type T1 is new T with ...; private type T1 is new T and I with ...; -- Private interface end P1; package P2 is -- We don't see private I type T2 is new T1 and I with null record; -- This is OK! end P2; package P1.Child_1 is -- We see private I type T2 is new T1 and I with null record; -- This is NOT OK end P1.Child_1; procedure P1.Child_2 is X : P2.T2; -- This is NOT OK, we see two instances of I in X But of course it is also possible to allow X as we do with other cases when operations get hidden by each other. In that scenario X.Foo will be rejected as ambiguous. Yes, when X were passed as a class-wide of another root type dispatching to Foo would take the hierarchy of I that this root type uses. It is all consistent. Y : T1'Class := ...; -- This OK, we see only private I begin Y.Foo; -- This dispatches on I inherited in P1, WYSIWYG procedure Public is X : P2.T2; -- This is OK, we respect privateness begin X.Foo; -- This dispatches on I inherited in P2 The important point is that inheritance can be additive as in the case when I is inherited once privately and once publicly. If succeeds then the outcome is *two* hierarchies. You cannot forbid that altogether, which is why you see it as a problem. It is not a problem, just let it be. We would also allow P1.Child_1 when the programmer states that I is inherited additively. The use case for additive inheritance is multiple linked-lists: type Node is limited interface; function Next (X : Node) return Node'Class; ... type IO_Queue is new Node and Node with ...; Each item participates in two lists, the list of requests and the list of requests from the same task (i.e. to abort them when the task completes). > The problem here is that only (2) respects privacy at all; Right. The user must resolve conflict when it appears. E.g. type IO_Queue is new Node as Request_List and Node as Task_List with ...; function Next_IO_Request ... renames Request_List.Next; function Next_Task_Request ... renames Task_List.Next; I leave syntax to imagination. >> Use-clauses, nesting, generic formals have *exactly* same issues there is >> absolutely nothing special in inheritance. > > And all of those are also evil. :-) Yes, the world is a sad place. (:-)) > They introduce significant maintenance > problems all of the time. And they don't have the problem of requiring > visibility on private things to resolve the conflicts. (For all of the > above, private things stay private.) True, and we could do same for inheritance. -- Regards, Dmitry A. Kazakov http://www.dmitry-kazakov.de