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,FREEMAIL_FROM autolearn=unavailable autolearn_force=no version=3.4.4 X-Received: by 10.13.254.67 with SMTP id o64mr8089244ywf.164.1495320702931; Sat, 20 May 2017 15:51:42 -0700 (PDT) X-Received: by 10.157.34.229 with SMTP id y92mr343732ota.15.1495320702881; Sat, 20 May 2017 15:51:42 -0700 (PDT) Path: eternal-september.org!reader01.eternal-september.org!reader02.eternal-september.org!news.eternal-september.org!news.eternal-september.org!feeder.eternal-september.org!news.glorb.com!l39no631823qtb.0!news-out.google.com!m134ni4291itb.0!nntp.google.com!67no1023874itx.0!postnews.google.com!glegroupsg2000goo.googlegroups.com!not-for-mail Newsgroups: comp.lang.ada Date: Sat, 20 May 2017 15:51:42 -0700 (PDT) In-Reply-To: Complaints-To: groups-abuse@google.com Injection-Info: glegroupsg2000goo.googlegroups.com; posting-host=173.71.201.205; posting-account=QF6XPQoAAABce2NyPxxDAaKdAkN6RgAf NNTP-Posting-Host: 173.71.201.205 References: User-Agent: G2/1.0 MIME-Version: 1.0 Message-ID: <4a47e4cd-829c-4451-abf1-82cf60b67706@googlegroups.com> Subject: Re: Preventing private procedure visibility being made public through extension From: Jere Injection-Date: Sat, 20 May 2017 22:51:42 +0000 Content-Type: text/plain; charset="UTF-8" Xref: news.eternal-september.org comp.lang.ada:46828 Date: 2017-05-20T15:51:42-07:00 List-Id: On Saturday, May 20, 2017 at 4:32:07 PM UTC-4, Dmitry A. Kazakov wrote: > On 2017-05-20 19:33, Jere wrote: > > Is there a way for me to prevent extending types from making > > the procedure public again? > > It is public. That was the decision made in the package Base. The > package Derived has no say on that. > > ---------------------------------- > The actual problem you have is parallel types hierarchies. You want to > derive tied instances of Base_Type'Class and Base_Param'Class. > > Base_Type ----- Base_Param > | | > Derived_Type -- Derived_Param > > This requires > > 1. Full multiple dispatch > 2. Dispatch constrained to certain combinations (parallel hierarchies) > > This is not supported in Ada (or in any other OO language I am aware of) If I understand your definitions correctly, C++ supports this. It can fully dispatch on any number of types since dispatch is tied to the function and not the type itself. C++ does have its own problems though. I do know that C++ supports hiding of functions by making them private in the extending class. I was hoping Ada did as well. I don't mind if dispatching runs the private versions, I can protect against that, but I didn't want clients using the methods as they break operation of the extended class. I can implement your suggestion from below though. I don't like the loss of static type checking here, but if Ada has not viable options here, then that may be what I have to do. My real issue is with how the constructors for the tagged type in the library are done. I want my derived type to work with the constructors defined in the library, which means it has to extend one of the types defined in the library itself. But I don't want clients to extend my class and use the inherited constructors from the base class because they'll break my extended class. My alternate solution was to use composition, but it really feels inelegant in this case. I did: package Derived is type Base_Access is access all Base.Base_Type; type Derived_Type is tagged limited private; procedure Something (Obj : Derived_Type; Value : Derived_Param'Class) is null; procedure Get_Access(Obj : Derived_Type) return Base_Access; private type Derived_Type is tagged limited record Param : Base.Base_Type; end record; end Derived; and Get_Access just returns Param'Unchecked_Access. When I want to use the library methods, I use that to pass back the correct type for them. I really don't like doing this. I don't like using access types for one. It's also doesn't feel like a very clean way because you have to do something out of the ordinary just to use the class like it was meant to be. The actual use case is Gnoga. All of the constructors (the Create procedures) require parent to be of type Gnoga.Gui.Base.Base_Type'Class, but I really want my Dialog_Type constructor to only accept parents of type Gnoga.Gui.Window.Window_Type'Class. But it also has to publicly extend Gnoga.Gui.Base.Base_Type (or I use Gnoga.Gui.View.View_Base_Type) so that other controls can create themselves in it. This opens my type and types that extend it to being thrashed by calls to Create_From_HTML and so on. Similar to your suggestion, I can override them and raise an exception...it just feels clunky. I was just hoping for something better from a static checking perspective. There was a discussion in the Gnoga mailing list if you are wanting more concrete examples. I was just simplifying it for here to see if there was a language defined way to get what I needed statically. It sounds like there isn't.