comp.lang.ada
 help / color / mirror / Atom feed
From: "Dmitry A. Kazakov" <mailbox@dmitry-kazakov.de>
Subject: Re: Class-wide types algebra
Date: Sat, 1 Oct 2016 10:35:55 +0200
Date: 2016-10-01T10:35:55+02:00	[thread overview]
Message-ID: <nsnsho$6om$1@gioia.aioe.org> (raw)
In-Reply-To: nsnilj$cn0$1@franka.jacob-sparre.dk

On 2016-10-01 07:47, Randy Brukardt wrote:
> "Dmitry A. Kazakov" <mailbox@dmitry-kazakov.de> wrote in message
> news:nsjrjo$lg8$1@gioia.aioe.org...
>> On 2016-09-29 20:44, Randy Brukardt wrote:
>>> "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.).
>>
>> No, you cannot, you don't see if the type inherits the interface, so you
>> cannot convert to its class.
>
> We're talking about the type that both publically and privately implements
> the same interface.

In the example provided it is P1.Child_1.T2.

> (The private one inherited from the parent, the public
> one directly added.) And we're talking about a conversion that occurs where
> the private interface is visible (so *both* copies of the interface are
> visible).

What converted to the type? But it is irrelevant anyway. The interface 
instances were already visible in the private part of the package where 
the offending type was declared. The conflict was *already* resolved 
there, or the type declaration rejected.

>>> Which overriding operation do you get?
>>
>> None, that is illegal, the type does not implement the interface inherited
>> privately. There is no overriding, there is no class in any public scope.
>
> You're not thinking broadly enough about all of the possible combinations of
> public and private inheritance. It just doesn't work. Yes, the "normal"
> cases work, but we have to allow all possibilities (or we're breaking
> privacy).  In particular, when you are in the private scope, you can see both
> interfaces.

I don't understand why you think so. Can you provide an example with the 
type declarations I gave?

>>> How does it chose which interface to use?
>>
>> The one visible in this context. There is no unresolved conflicts, in any
>> given context it is unambiguous.
>
> ??? Both interfaces are visible in the private context. How could they not
> be both visible  (they're distinct)?

Because declaration of P1.Child_1.T2 is illegal. To make it legal at 
least one of the interfaces must be renamed.

>> By violating privacy, by introducing ugly artifacts, by piling up nonsense
>> rules...
>
> There's no violation of privacy. It's illegal to add an interface in a
> private part,

That constitutes violation of privacy. Usually it is more that you can 
do privately than publicly (:-))

>>>> 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.)
>>
>> It breaks nothing. You get two hierarchies independent on each other.
>
> Sorry, but you don't have any idea how interface dispatching works. It's
> typically done with some sort of lookup table (since the typical solution of
> ensuring that all of the slots are the same in all of descendants does not
> work when multiple inheritance is allowed).

The slots in the dispatching table are different because interfaces are 
different.

> That works because there is only
> one copy of each interface, so there is no need to worry about where they
> come from - one just needs a unique Id where they are declared. If there can
> be multiple copies, that doesn't work.

The copies get different IDs in the combined dispatching table, that is 
the purpose of renaming/conflict resolution.

> And since these are runtime
> operations

It is no different from how dispatching works under MI. You must slide 
the table when moving toward the roots. In most general case you have

    Tag x Operation -> Body

So it is T x I(1) and T x I(2), both different. You might have 
difficulties with interpretation re-dispatch if a body is inherited 
as-as, but that is only for full MI, we don't have still. Clearly 
I'Class in an inherited body must mean "the class of my I".

>> You already can do just this with ease:
>>
>>    generic
>>    package P is
>>       type I is interface;
>>       procedure Foo (X : I) is abstract;
>>    end P;
>>
>>    package P1 is new P;
>>    package P2 is new P;
>>
>>    type T is new P1.I and P2.I with null record;
>>    overriding procedure Foo (X : T);
>
> P1.I and P2.I are two different types.

BINGO!

> In the privacy case, you are getting
> two copies of the same type.

No, you get two different types (interfaces) if the conflict resolved.

> Not remotely the same thing. (You can tell the
> difference by trying to call a global class-wide operation that has a
> parameter of the interface. For this example, that won't work for both
> interfaces -- one or the other isn't going to be allowed. For the private
> example, one could call that routine with either interface (because they
> have the same name) -- that's the crux of the problem.

Exactly, it is ambiguous just same as if in the body of P there were

    Bar (X : I'Class);

overloaded from instances of P1 and P2.

>> How is it different from:
>>
>>    type T is new I and I with null record;
>
> There is only one copy of the interface in this type.

No, there are two. And calling to Bar is ambiguous. The conflict must be 
resolved by naming a distinct I's in T. Once they named T gets 
independent sets of slots for each of the primitive operations of I. To 
be able to call Bar where you see both I's you will have to explicitly 
convert T to either of two I'Class. That will slide to the corresponding 
section of the dispatching table corresponding to the chosen I.

-- 
Regards,
Dmitry A. Kazakov
http://www.dmitry-kazakov.de


  reply	other threads:[~2016-10-01  8:35 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
2016-09-29 19:55                   ` Dmitry A. Kazakov
2016-10-01  5:47                     ` Randy Brukardt
2016-10-01  8:35                       ` Dmitry A. Kazakov [this message]
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