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!feeder.eternal-september.org!nntp-feed.chiark.greenend.org.uk!ewrotcd!newsfeed.xs3.de!io.xs3.de!news.jacob-sparre.dk!franka.jacob-sparre.dk!pnx.dk!.POSTED.rrsoftware.com!not-for-mail From: "Randy Brukardt" Newsgroups: comp.lang.ada Subject: Re: Full view of a private partial view cannot be a subtype Date: Tue, 5 Dec 2017 14:12:41 -0600 Organization: JSA Research & Innovation Message-ID: References: <5b32a99e-04e5-4adb-8b42-88e485570641@googlegroups.com> Injection-Date: Tue, 5 Dec 2017 20:12:42 -0000 (UTC) Injection-Info: franka.jacob-sparre.dk; posting-host="rrsoftware.com:24.196.82.226"; logging-data="1679"; mail-complaints-to="news@jacob-sparre.dk" X-Priority: 3 X-MSMail-Priority: Normal X-Newsreader: Microsoft Outlook Express 6.00.2900.5931 X-RFC2646: Format=Flowed; Original X-MimeOLE: Produced By Microsoft MimeOLE V6.00.2900.7246 Xref: reader02.eternal-september.org comp.lang.ada:49383 Date: 2017-12-05T14:12:41-06:00 List-Id: "Jere" wrote in message news:5b32a99e-04e5-4adb-8b42-88e485570641@googlegroups.com... > On Monday, December 4, 2017 at 3:49:54 PM UTC-5, Randy Brukardt wrote: >> "Jere" wrote in message >> ... >> > package New_Type1 is >> > subtype Instance is Base.Instance; >> > procedure Operation(Object : in out Instance); >> > >> > private >> > >> > procedure Operation(Object : in out Instance) renames >> > Base.Operation; >> > end New_Type1; >> > >> > (NOTE: is there a better way to do this?) >> >> No, no better way yet, but maybe (large maybe here) in Ada 2020. (I'm >> leaving out all details because none have been determined yet and perhaps >> never will be for Ada 2020.) > > Sounds intriguing! > >> >> > This is all well and good, but sometimes while I as an implementer >> > want this kind of relationship, I don't necessarily want to expose >> > that relationship outside the private section of a package. Here I >> > run into a problem as I cannot (as far as I can tell) do: >> > >> > package New_Type2 is >> > type Instance is tagged limited private; >> > procedure Operation(Object : in out Instance); >> > private >> > subtype Instance is Base.Instance; >> >> This is illegal; a private type has to be completed with a full type, not >> a >> subtype. (If you have a compiler that is allowing this, it is >> confused...) > > Yep, that was my comment. Basically I have a low level package that is > used > to create many higher level, more client friendly packages: > > generic > type Input_Type(<>); > with procedure Really_Dangerous_To_Call(Object : Input_Type); > Value : Integer; > package Low_Level_Package > > type My_Type is private; > type Numeric_Type is ; > > function Client_Friendly_Procedure > (Object : My_Type) > return Numeric_Type; > > > > private > ... > > end Low_Level_Package; > > and I want to use it to make some more client friendly versions. > The procedure, Really_Dangerous_To_Call, isn't meant to be called > directly for a client. It is meant to be used to setup implementations > behind the client packages. If you control the entire design of the type hierarchy, the best way to do this is to put "Really_Dangerous_to_Call" into the private part of the root operation, and declare the child types in child packages. Then, the child types can call the routine but clients cannot. (An added advantage is that Really_Dangerous_to_Call can be dispatching in such a design.) Claw is organized this way, so it's pretty certain that Ada compilers can properly process such an organization. This looks something like: package Claw is ... -- Hundreds of lines of other stuff... type Root_Window_Type is abstract tagged private; -- Actually, derived from Controlled. ... -- Public dispatching operations available for all Windows, like Move, Resize, etc. private procedure Really_Dangerous_to_Call (Window : in out Root_Window_Type); -- Other private dispatching operations and the full declaration of Root_Window_Type. end Claw; package Claw.Basic is type Basic_Window_Type is new Root_Window_Type with private; ... -- Public for Basic_Windows, including those available for all Windows, like Move, Resize, etc. private -- Can override Really_Dangerous_to_Call here, if needed. end Claw.Basic; The body of Claw.Basic can call Really_Dangerous_to_Call if needed, but clients can't. If you only need class-wide operations, you can also do this with a private package (which then can only be withed by children of the parent package, and not visibly). Claw uses this to hide the actual message handlers from the clients (so the client can't mess them up), and uses dispatching to call them (so each Claw type can have a custom message handler if needed -- and it is usually needed). Randy.