comp.lang.ada
 help / color / mirror / Atom feed
From: "Randy Brukardt" <randy@rrsoftware.com>
Subject: Re: Class-wide types algebra
Date: Thu, 29 Sep 2016 13:44:56 -0500
Date: 2016-09-29T13:44:56-05:00	[thread overview]
Message-ID: <nsjnei$t8v$1@franka.jacob-sparre.dk> (raw)
In-Reply-To: nsii37$fl3$1@gioia.aioe.org

"Dmitry A. Kazakov" <mailbox@dmitry-kazakov.de> wrote in message 
news:nsii37$fl3$1@gioia.aioe.org...
> On 28/09/2016 22:17, Randy Brukardt wrote:
>> "Dmitry A. Kazakov" <mailbox@dmitry-kazakov.de> 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.

??? You can always convert an object of the type to the class-wide interface 
(which is legal in this scenario, even if not in the private part), and make 
a dispatching call. (That's the case that's a problem.). Which overriding 
operation do you get? If it depends on visibility, you have madness (what 
happens depends on where it is written - yuck). If it doesn't depend on 
visibility, the implementation of the original private type is going to end 
up with the new operations, even though those were not overridden (which is 
likely to break something - essentially you'd be getting the wrong copy of 
the interface).

That of course could occur implicitly inside of a class-wide interface 
operation called by the private implementation (which is the reason for 
using interfaces in the first place), so it's a real issue.

> 2. Where type's primitive operations are visible you cannot derive without 
> resolving the conflict between hierarchies.

Sure. But that doesn't fix anything.

> From this follows that you cannot use the type in the context where hidden 
> operations are visible!

No problem, but the problem is with the type with two copies of the 
interface. How does the conversion to I'Class work (that conversion is 
implicit in calls to class-wide subprograms)? How does it chose which 
interface to use? The correct answer depends on what the programmer 
intended, and that something a compiler (or programming language) can't 
know.

...
> 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

Actually, this is madness. Nothing "consistent" about it. Why? Because if 
you move the call to some outside routine (say some other dispatching 
operation), the meaning changes. Which means that one can't use 
abstractions. Very, very bad.

> 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.

Well, actually we do: we forbid the private inheritance completely, because 
there is no consistent and sensible set of rules for what it would mean.

> It is not a problem, just let it be.

The implementation of two copies of the same interface would break any of 
the existing algorithms for implementing interfaces. (I have absolutely no 
idea how that could be accomplished; it would depend on how the dispatching 
rules were eventually worked out.)

...
>> 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.

Doesn't help, as noted above.

               Randy.



  reply	other threads:[~2016-09-29 18:44 UTC|newest]

Thread overview: 14+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2016-09-12 20:26 Class-wide types algebra Dmitry A. Kazakov
2016-09-12 21:12 ` rieachus
2016-09-12 21:39   ` Dmitry A. Kazakov
2016-09-13 11:46     ` rieachus
2016-09-13 12:26       ` Dmitry A. Kazakov
2016-09-28  0:05         ` Randy Brukardt
2016-09-28  7:31           ` Dmitry A. Kazakov
2016-09-28 20:17             ` Randy Brukardt
2016-09-29  8:06               ` Dmitry A. Kazakov
2016-09-29 18:44                 ` Randy Brukardt [this message]
2016-09-29 19:55                   ` Dmitry A. Kazakov
2016-10-01  5:47                     ` Randy Brukardt
2016-10-01  8:35                       ` Dmitry A. Kazakov
2016-10-05 20:42                         ` Randy Brukardt
replies disabled

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox