comp.lang.ada
 help / color / mirror / Atom feed
From: "Randy Brukardt" <randy@rrsoftware.com>
Subject: Re: Ada design bug or GNAT bug?
Date: Fri, 3 Jul 2015 12:33:07 -0500
Date: 2015-07-03T12:33:07-05:00	[thread overview]
Message-ID: <mn6h0k$cno$1@loke.gir.dk> (raw)
In-Reply-To: 1oyc7ksu2lrwz.1h4pqchzcyfzt.dlg@40tude.net

"Dmitry A. Kazakov" <mailbox@dmitry-kazakov.de> wrote in message 
news:1oyc7ksu2lrwz.1h4pqchzcyfzt.dlg@40tude.net...
> On Thu, 2 Jul 2015 17:22:08 -0500, Randy Brukardt wrote:
>
>> "Dmitry A. Kazakov" <mailbox@dmitry-kazakov.de> wrote in message
>> news:ykiyl6yc44or$.19365hv76bzoi.dlg@40tude.net...
>>> On Mon, 22 Jun 2015 12:39:16 -0500, Randy Brukardt wrote:
>>>
>>>> We don't have a choice about allowing hidden controlling results and
>>>> controlling access results (unless, of course, we want to abandon real
>>>> privacy, which we're not going to do).
>>>
>>> If function is invisible it is, and its result is as well.
>>
>> Not really, because you can still dispatch to it (if the dispatching is
>> somewhere that the private function is visible); dispatching does not
>> respect privacy (as privacy is only a compile-time, not runtime, 
>> concept).
>
> I don't see a scenario where you could dispatch on an invisible primitive
> operation. First you must get into a context where you would have a view 
> of
> your type having that operation. This context cannot exist without another
> context where the type gets derived. In that context you must have
> overridden the operation. Where is a problem? Is it related to MI? [But 
> Ada
> does not respect privacy, when it checks inherited stuff, it does this as
> if in a full view of the type, which is another language bug, but still no
> problem.]

This seeems confused, and you ask the right question later...

>> I realize that you hate redispatching (a point that I tend to agree with 
>> you
>> on), but it's possible, and it's needed some part of the time (maybe 10% 
>> or
>> even less, but more than 0%), so it exists and has to be taken into 
>> account.
>
> But even if you convert to the class-wide you don't get visibility of the
> operation. In the scenario:
>
>   type T3 is new T1 with private;
> private
>   type T3 is new T2 with null record; -- Legal!
>
> a public client could not convert a T3 object to T2'Class. Could it?

No, but a private client can, and if you have a public type T4 derived from 
T3, it would not have the function operation.

package P2 is
   type T3 is new T1 with private;
   procedure Do_It (X : inT3);
private
   type T3 is new T2 with null record; -- Legal!
end P2;

with P2;
package P3 is
   type T4 is new P2.T3 with C : Character; end record; -- No defined F 
here.
end P3;

with P2, P3;
procedure Main is
   Obj : P3.T4;
begin
   Obj.Do_It; -- Calls Do_It with a T4 operation, does not have F.
end Main;

package body P2 is
   procedure Do_It (X : in T3) is
   begin
       if T2'Class(X) = F then -- Dispatching call to F, tag is T4, but 
there is no F for T4. Ouch.
           ...
       end if;
   end Do_It;
end P2;

>>>> have the feature at all (which is where I would stand).
>>>
>>> I don't see connection to anonymous access types, the rule applies to
>>> tagged results as well:
>>>
>>> package P1 is
>>>   type T1 is tagged null record;
>>>   type T2 is new T1 with null record;
>>>   function Foo return T2;
>>> end P1;
>>>
>>> with P1; use P1;
>>> package P2 is
>>>   type T3 is new T1 with private;
>>> private
>>>   type T3 is new T2 with null record; -- Legal!
>>
>> This is only legal because of a hack, which I was very much against
>> introducing. If you have an extension component, this is illegal:
>>
>>     type T4 is new T2 with record C : Character := '1'; end record; --
>> Illegal!!!
>
> Yes, the hack you mean is contravariance of an out argument or result 
> based
> on a guess about the type implementation (null extension). It is wrong 
> from
> the strong typing POV.
>
>>> end P2;
>>
>> I have tried to find a way to avoid this maintenance hazard (it's 
>> especially
>> bad for mix-in generics), but I haven't gotten any traction to date. We
>> could (if all of the extension components have defaults) automatically do
>> this as we do for null record, but the problem is that making overriding
>> required often detects bugs (failure to create a proper overriding). Plus
>> the problem of incompatibility (only in obscure cases).
>
> No. I know you don't believe in science and proofs but still, 
> conravariance
> in outputs is just wrong (under type extension).
>
> Instead of ugly hacks we better have had some delegation/body-composition
> methods at the declaration place to be able to tell that the overriding is
> basically the parent's implementation. We already allowed such stuff, e.g.
>
>   procedure Foo (...) is null;
>
> We have ugly executable precondition code at the declaration side. Why not
> to allow this for functions?

I don't understand what you mean. An expression function can be given as the 
overriding, but that doesn't help if you don't have the needed visibility to 
see the components in question (an aggregate is only legal if no private 
types are involved -- we tried to find a way to relax that for Ada 2005, but 
it just got way too messy).

>>> with P1; use P1;
>>> package P2 is
>>>   type T3 is new T1 with private;
>>> private
>>>   type T3 is new T2 with null record;
>>>   overriding function Foo return T3; -- ILLEGAL!
>>> end P2;
>>>
>>> As such the rule does not make any sense. You shall under no 
>>> circumstance
>>> prohibit overriding of inherited operations.
>>
>> That's only possible if you prohibit any extensions of T3. (Otherwise, 
>> you
>> get the dispatching problems that I noted previously, or you have to 
>> break
>> privacy by making the derived type illegal for something that is not
>> visible.) We've talked a bit about having such an aspect, but it is 
>> messy.
>
> Could you provide an example of dispatching problems you have in mind?

Done, see above.

>> To summarize: it's a bad interaction between privacy and things that 
>> require
>> overriding (abstract subprograms follow the same rules for the same
>> reasons). There's no real solution, else you could call abstract
>> subprograms -- and then what??
>
> Honestly I never understood how that could happen. The dispatching table
> must be defined for any non-abstract instance. This is statically 
> enforced,
> isn't it?

Right -- that's why you get the rule requiring visible operations. 
Statically enforcing it otherwise would require breaking privacy, which we 
won't do (outside of representation clauses, for which privacy doesn't make 
any sense anyway).

                            Randy. 




  reply	other threads:[~2015-07-03 17:33 UTC|newest]

Thread overview: 46+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2015-06-20 18:55 Ada design bug or GNAT bug? Dmitry A. Kazakov
2015-06-21  2:42 ` Randy Brukardt
2015-06-21  6:47   ` Dmitry A. Kazakov
2015-06-22 17:39     ` Randy Brukardt
2015-06-22 18:16       ` Dmitry A. Kazakov
2015-06-23 11:00         ` G.B.
2015-06-23 14:27           ` Dmitry A. Kazakov
2015-06-23 11:45         ` G.B.
2015-06-23 14:30           ` Dmitry A. Kazakov
2015-07-02 22:22         ` Randy Brukardt
2015-07-03  8:02           ` Dmitry A. Kazakov
2015-07-03 17:33             ` Randy Brukardt [this message]
2015-07-03 21:34               ` Dmitry A. Kazakov
2015-07-04  3:11                 ` Randy Brukardt
2015-07-04 12:14                   ` Dmitry A. Kazakov
2015-07-05  0:53                     ` Randy Brukardt
2015-06-22 18:27       ` Shark8
2015-06-23 11:51         ` vincent.diemunsch
2015-06-23 19:55           ` Shark8
2015-06-23 13:06         ` vincent.diemunsch
2015-06-23 14:30           ` David Botton
2015-06-23 15:57             ` Niklas Holsti
2015-06-23 16:01               ` G.B.
2015-06-23 18:05               ` David Botton
2015-06-23 19:38               ` David Botton
2015-06-23 14:38           ` Dmitry A. Kazakov
2015-06-23 16:57             ` Vincent
2015-06-23 17:15               ` Dmitry A. Kazakov
2015-06-23 19:14                 ` vincent.diemunsch
2015-06-23 19:33                   ` Dmitry A. Kazakov
2015-06-23 17:42           ` Jeffrey R. Carter
2015-07-02 22:06           ` Randy Brukardt
2015-07-04  1:52             ` Shark8
2015-07-04  3:24               ` Randy Brukardt
2015-07-04 11:02                 ` Build-in-place semantics? (Was: Ada design bug or GNAT bug?) Jacob Sparre Andersen
2015-07-04 12:15                   ` Dmitry A. Kazakov
2015-07-05  0:45                     ` Randy Brukardt
2015-07-05  7:10                       ` Dmitry A. Kazakov
2015-07-05  0:40                   ` Randy Brukardt
2015-07-04 14:05                 ` Ada design bug or GNAT bug? Bob Duff
2015-07-04  7:46               ` Simon Wright
2015-07-04 12:00                 ` Björn Lundin
2015-07-05  0:48                   ` Randy Brukardt
2015-07-06 12:37             ` Vincent
2015-07-06 20:05               ` Randy Brukardt
2015-07-07  8:06               ` Dmitry A. Kazakov
replies disabled

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