comp.lang.ada
 help / color / mirror / Atom feed
* OOP in Ada: Alternatives for "protected" scope
@ 2012-05-03 21:27 Felix Krause
  2012-05-03 21:56 ` Dmitry A. Kazakov
                   ` (3 more replies)
  0 siblings, 4 replies; 12+ messages in thread
From: Felix Krause @ 2012-05-03 21:27 UTC (permalink / raw)


Hi all,

I have used Ada's OOP-features for quite some time now, and there is 
one thing that really bothers me: Ada does not provide any class-based 
visibility scopes. In some cases, the package-based approach to 
visibility / information hiding just doesn't seem to provide enough 
flexibility. Let me give an example:

I have some abstract class A, defined in package P_A. This class 
provides some functionality as procedure Do_Something. Now there is 
some calculation to be done while execution Do_Something which cannot 
be defined in A. Therefore, it is left to the specific child classes of 
abstract class A to implement that calculation. The code might look 
like this:

package P_A is
   type A is abstract tagged private;

   procedure Do_Something (Object : in out A);

   function Calculate (Object : in out A) return Integer is abstract;
private
   -- define A here...
end P_A;

package body P_A is
   procedure Do_Something (Object : in out A) is
      Var : Integer;
   begin
      -- some useful code here…

      -- let the specific child class define this calculation
      Var := Calculate (Object);

      -- some more useful code here...
   end Do_Something;
end P_A;

The function Calculate should only be used internally. I do not see a 
good way to enforce this with Ada: I do not want to move it to P_A's 
private part, because child classes of A should not be required to be 
located in sub-packages of P_A. (It's also forbidden for an abstract 
function to reside in the private part.)

In languages like Java and C#, there is a "protected" scope to cope 
with this situation. Now of course these languages, unlike Ada, are 
based on OOP, so it is natural for them to provide class-based 
visibility scopes. My question is, how would one implement this kind of 
visibility in Ada?




^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: OOP in Ada: Alternatives for "protected" scope
  2012-05-03 21:27 OOP in Ada: Alternatives for "protected" scope Felix Krause
@ 2012-05-03 21:56 ` Dmitry A. Kazakov
  2012-05-04 18:48   ` Felix Krause
  2012-05-03 23:34 ` Randy Brukardt
                   ` (2 subsequent siblings)
  3 siblings, 1 reply; 12+ messages in thread
From: Dmitry A. Kazakov @ 2012-05-03 21:56 UTC (permalink / raw)


On Thu, 3 May 2012 23:27:55 +0200, Felix Krause wrote:

> I have some abstract class A, defined in package P_A. This class 
> provides some functionality as procedure Do_Something. Now there is 
> some calculation to be done while execution Do_Something which cannot 
> be defined in A. Therefore, it is left to the specific child classes of 
> abstract class A to implement that calculation. The code might look 
> like this:

In that case Do_Something cannot be a primitive operation or else the
operation called from it must re-dispatch.

> package P_A is
>    type A is abstract tagged private;
> 
>    procedure Do_Something (Object : in out A);
>
>    function Calculate (Object : in out A) return Integer is abstract;

This is illegal in Ada 95-2005.

> private
>    -- define A here...
> end P_A;
> 
> package body P_A is
>    procedure Do_Something (Object : in out A) is
>       Var : Integer;
>    begin
>       -- some useful code here嚙皺
> 
>       -- let the specific child class define this calculation
>       Var := Calculate (Object);

This is wrong, it should have been

   Var := Calculate (A'Class (Object));

or else Do_Something should be declared class-wide:

   procedure Do_Something (Object : in out A'Class);

>       -- some more useful code here...
>    end Do_Something;
> end P_A;
>
> The function Calculate should only be used internally. I do not see a 
> good way to enforce this with Ada: I do not want to move it to P_A's 
> private part, because child classes of A should not be required to be 
> located in sub-packages of P_A. (It's also forbidden for an abstract 
> function to reside in the private part.)

If Do_Something varies in children they should override it. The reusable
parts common for all children can be factored out as a private class-wide
operation.

All children having access to private operations must be declared in
children packages.

   package P is
      type A is abstract tagged private;   
      procedure Do_Something (Object : in out A) is abstract;
   private
      ...
      procedure Do_Prologue  (Object : in out A'Class);
      procedure Do_Epilogue  (Object : in out A'Class);
   end P;

   package P.Q is
      type B is new A with private;
      overriding procedure Do_Something (Object : in out B);
      ...
   end P.Q;

   package body P.Q is
      procedure Do_Something (Object : in out B) is
      begin
          Do_Prologue (Object);
          ... -- Do specific calculations
          Do_Epilogue (Object);
      end Do_Something;
   end P.Q;

> In languages like Java and C#, there is a "protected" scope to cope 
> with this situation.

This is exactly what Ada's private is. The correspondence goes as follows:

"Public" <-> Ada' public operation
"Protected" <-> Ada's private operation
"Private" <-> An operation defined in the package body

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



^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: OOP in Ada: Alternatives for "protected" scope
  2012-05-03 21:27 OOP in Ada: Alternatives for "protected" scope Felix Krause
  2012-05-03 21:56 ` Dmitry A. Kazakov
@ 2012-05-03 23:34 ` Randy Brukardt
  2012-05-04  1:41 ` BrianG
  2012-05-04 10:37 ` Georg Bauhaus
  3 siblings, 0 replies; 12+ messages in thread
From: Randy Brukardt @ 2012-05-03 23:34 UTC (permalink / raw)


"Felix Krause" <flyx@isobeef.org> wrote in message 
news:jnut8r$aqb$1@online.de...
...
> The function Calculate should only be used internally. I do not see a good 
> way to enforce this with Ada: I do not want to move it to P_A's private 
> part, because child classes of A should not be required to be located in 
> sub-packages of P_A. (It's also forbidden for an abstract function to 
> reside in the private part.)
>
> In languages like Java and C#, there is a "protected" scope to cope with 
> this situation. Now of course these languages, unlike Ada, are based on 
> OOP, so it is natural for them to provide class-based visibility scopes. 
> My question is, how would one implement this kind of visibility in Ada?

You gave the answer above, and then said you didn't like it. Well, not 
everything is as we wish it would be!

For the record, Claw used the technique of putting "private" (what you 
called "protected") operations in the private part extensively. Most the 
root types were declared in package Claw (no implementations there) and all 
of the child types were in child packages. It works pretty well, other than 
a gotcha that can happen when deriving from a sibling class (you can't 
override the private operation in that case). We (the ARG) tried to fix that 
for Ada 2012, but the interface mechanism created insurmountable problems 
(another reason I hate interfaces).

                                    Randy.





^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: OOP in Ada: Alternatives for "protected" scope
  2012-05-03 21:27 OOP in Ada: Alternatives for "protected" scope Felix Krause
  2012-05-03 21:56 ` Dmitry A. Kazakov
  2012-05-03 23:34 ` Randy Brukardt
@ 2012-05-04  1:41 ` BrianG
  2012-05-04 10:37 ` Georg Bauhaus
  3 siblings, 0 replies; 12+ messages in thread
From: BrianG @ 2012-05-04  1:41 UTC (permalink / raw)


On 05/03/2012 05:27 PM, Felix Krause wrote:
...

>
> The function Calculate should only be used internally. I do not see a
> good way to enforce this with Ada: I do not want to move it to P_A's
> private part, because child classes of A should not be required to be
> located in sub-packages of P_A.

Since those other languages' Class is equivalent to a combination of 
Ada's Tagged Type, associated Primitive Operations (etc.), and 
containing Package (i.e. "Class" provides the container and name-space, 
part of the other-language definition of "OOP", which Ada provides in a 
more general way with Packages), this is equivalent to saying those 
languages should not require a derived type to be contained within a 
Class derived from the parent.

-- 
---
BrianG
000
@[Google's email domain]
.com



^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: OOP in Ada: Alternatives for "protected" scope
  2012-05-03 21:27 OOP in Ada: Alternatives for "protected" scope Felix Krause
                   ` (2 preceding siblings ...)
  2012-05-04  1:41 ` BrianG
@ 2012-05-04 10:37 ` Georg Bauhaus
  2012-05-04 10:43   ` Georg Bauhaus
  2012-05-04 12:10   ` Dmitry A. Kazakov
  3 siblings, 2 replies; 12+ messages in thread
From: Georg Bauhaus @ 2012-05-04 10:37 UTC (permalink / raw)


On 03.05.12 23:27, Felix Krause wrote:
> Now there is some calculation to be done while execution Do_Something which cannot be defined in A.
> (...)
> In languages like Java and C#, there is a "protected" scope to cope with this situation.

There are some O-O solutions.

One solution is outlined by at least on Java guru, and by the Objective-C
programming model in ***step.  In short, replace procedural style
with O-O style (sounds odd, but that's really what it does;
the dependence of A/Do_Something on Calculate is an implicit
procedural thing).

with Calculators;
package P_A is

    type A is abstract tagged private;

    procedure Do_Something (Object : in out A);


    --
    -- Add your type of computation here to be performed
    -- at some time during the execution of Do_Something:
    --
    procedure Link
        (Object : in out A;
         Computation: Calculators.Calculator'Class);

private

    type Circuits is
        access constant Calculators.Calculator'Class;

    type A is abstract tagged record
       Machine : Circuits;
    end record;

end P_A;

If necessary things can be moved further down the package and/or
type hierarchy if the presence of a calculation should be hidden
at the top level.




^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: OOP in Ada: Alternatives for "protected" scope
  2012-05-04 10:37 ` Georg Bauhaus
@ 2012-05-04 10:43   ` Georg Bauhaus
  2012-05-04 12:10   ` Dmitry A. Kazakov
  1 sibling, 0 replies; 12+ messages in thread
From: Georg Bauhaus @ 2012-05-04 10:43 UTC (permalink / raw)


That was too quick; but moving "private" before Link in the
example gets around the "protected" operations of abstract
types needing to be public:

private
      --
      -- Add your type of computation here to be performed
      -- at some time during the execution of Do_Something:
      --
      procedure Link
          (Object : in out A;
           Computation: Calculators.Calculator'Class);




^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: OOP in Ada: Alternatives for "protected" scope
  2012-05-04 10:37 ` Georg Bauhaus
  2012-05-04 10:43   ` Georg Bauhaus
@ 2012-05-04 12:10   ` Dmitry A. Kazakov
  1 sibling, 0 replies; 12+ messages in thread
From: Dmitry A. Kazakov @ 2012-05-04 12:10 UTC (permalink / raw)


On Fri, 04 May 2012 12:37:01 +0200, Georg Bauhaus wrote:

> On 03.05.12 23:27, Felix Krause wrote:
>> Now there is some calculation to be done while execution Do_Something
>> which cannot be defined in A.
>> (...)
>> In languages like Java and C#, there is a "protected" scope to cope with this situation.
> 
> There are some O-O solutions.
> 
> One solution is outlined by at least on Java guru, and by the Objective-C
> programming model in ***step.  In short, replace procedural style
> with O-O style (sounds odd, but that's really what it does;
> the dependence of A/Do_Something on Calculate is an implicit
> procedural thing).
> 
> with Calculators;
> package P_A is
> 
>     type A is abstract tagged private;
> 
>     procedure Do_Something (Object : in out A);
>     --
>     -- Add your type of computation here to be performed
>     -- at some time during the execution of Do_Something:
>     --
>     procedure Link
>         (Object : in out A;
>          Computation: Calculators.Calculator'Class);

Well, if additional type hierarchies are permitted, then a possible pattern
is mix-in + Rosen's trick:

package P is
   type A (<>) is tagged private;
   procedure Do_Something (Object : in out A);

private
   type Abstract_Formula is abstract tagged null record;
   function Calculate (Formula : Abstract_Formula; Object : A'Class)
      return Integer is abstract;

   type A (Formula : not null access Abstract_Formula'Class) is
      abstract tagged null record;
end P;

package body P is
   procedure Do_Something (Object : in out A) is
   begin
      ...
      Result := Object.Formula.Calculate (Object);
      ...
   end Do_Something;

Clients derive from Abstract_Formula their implementations, these instances
are mixed in with A, which need not to be derived from when only formula
changes.

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



^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: OOP in Ada: Alternatives for "protected" scope
  2012-05-03 21:56 ` Dmitry A. Kazakov
@ 2012-05-04 18:48   ` Felix Krause
  2012-05-04 22:00     ` Dmitry A. Kazakov
  2012-05-05  4:33     ` Shark8
  0 siblings, 2 replies; 12+ messages in thread
From: Felix Krause @ 2012-05-04 18:48 UTC (permalink / raw)


On 2012-05-03 21:56:51 +0000, Dmitry A. Kazakov said:
> 
> If Do_Something varies in children they should override it. The reusable
> parts common for all children can be factored out as a private class-wide
> operation.

Compared to my version (with redispatching issues fixed), this 
alternative enforces a weaker contract. It does not enforce the child 
classes to call Do_Prologue and Do_Epilogue when implementing 
Do_Something. While this fixes the problem that I cannot have an 
abstract method in the private part, I think the mix-in solution you 
suggested in your second post is a better way to handle this.

> All children having access to private operations must be declared in
> children packages.
> 
>    package P is
>       type A is abstract tagged private;
>       procedure Do_Something (Object : in out A) is abstract;
>    private
>       ...
>       procedure Do_Prologue  (Object : in out A'Class);
>       procedure Do_Epilogue  (Object : in out A'Class);
>    end P;
> 
>    package P.Q is
>       type B is new A with private;
>       overriding procedure Do_Something (Object : in out B);
>       ...
>    end P.Q;
> 
>    package body P.Q is
>       procedure Do_Something (Object : in out B) is
>       begin
>           Do_Prologue (Object);
>           ... -- Do specific calculations
>           Do_Epilogue (Object);
>       end Do_Something;
>    end P.Q;
> 
>> In languages like Java and C#, there is a "protected" scope to cope
>> with this situation.
> 
> This is exactly what Ada's private is. The correspondence goes as follows:
> 
> "Public" <-> Ada' public operation
> "Protected" <-> Ada's private operation
> "Private" <-> An operation defined in the package body

So, to be able to use these visibility scopes, the class hierarchy must 
follow the layout of the package hierarchy. I think this is a 
disadvantage for some reasons:

 * Given the scenario that you use an Ada software library containing 
tagged types, you have to subclass these types in child-packages within 
the package layout of the library. I for myself would rather want to 
place my code in the package hierarchy of my application.

 * It doesn't work with generics:

generic
   -- ...
package P is
   type A is tagged private;
   -- …
end P;

package Q is
   package P_Instance is new P (...);

   type B is new P_Instance.A with private;
end P.Q.R;

Any non-generic tagged type derived from an instance of a generic 
parent type cannot access that type's "protected" methods - as all 
child packages of a generic package also must be generic.




^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: OOP in Ada: Alternatives for "protected" scope
  2012-05-04 18:48   ` Felix Krause
@ 2012-05-04 22:00     ` Dmitry A. Kazakov
  2012-05-05  8:28       ` Felix Krause
  2012-05-05  4:33     ` Shark8
  1 sibling, 1 reply; 12+ messages in thread
From: Dmitry A. Kazakov @ 2012-05-04 22:00 UTC (permalink / raw)


On Fri, 4 May 2012 20:48:53 +0200, Felix Krause wrote:

> On 2012-05-03 21:56:51 +0000, Dmitry A. Kazakov said:
>> 
>> If Do_Something varies in children they should override it. The reusable
>> parts common for all children can be factored out as a private class-wide
>> operation.
> 
> Compared to my version (with redispatching issues fixed), this 
> alternative enforces a weaker contract.

I don't like re-dispatch, it is a design bug to me.

>> This is exactly what Ada's private is. The correspondence goes as follows:
>> 
>> "Public" <-> Ada' public operation
>> "Protected" <-> Ada's private operation
>> "Private" <-> An operation defined in the package body
> 
> So, to be able to use these visibility scopes, the class hierarchy must 
> follow the layout of the package hierarchy.

That depends on what you mean. Classes (types constituting them) stretch
across packages, as types don't live in the vacuum.

Ada separates types and visibility. Comparing to other languages it is a
great advantage. I understand that you see it differently, but that is
because you haven't yet accustomed to the Ada's model.

Note that Ada has another (inferior) model as well. It can be seen in Ada
protected and task types. They are mess. It was a mistake.

> I think this is a 
> disadvantage for some reasons:
> 
>  * Given the scenario that you use an Ada software library containing 
> tagged types, you have to subclass these types in child-packages within 
> the package layout of the library.

Only if you want to access private, i.e. implementation-dependent, stuff.
Note that when a package depends on the implementation details of another
package, this constitutes a tight coupling. Ada requires the programmer to
manifest this design decision in the form of a parent-child package
relation. This IMO is a good thing. You cannot access the implementation
details if you don't state your intention making it visible for the reader.
Note also that this decision is all on the child's side. In the competing
model, any derived type always get access, so the decision is on the parent
type side. This is a bad design because it forces the programmer to make
his choice early and, maybe, it does a wrong person.

> I for myself would rather want to 
> place my code in the package hierarchy of my application.

That is not a problem, you can rename packages.

>  * It doesn't work with generics:
> 
> generic
>    -- ...
> package P is
>    type A is tagged private;
>    -- 嚙皺
> end P;
> 
> package Q is
>    package P_Instance is new P (...);
> 
>    type B is new P_Instance.A with private;
> end P.Q.R;

You use a generic child:

generic
package P.Q is
   type B is new A with private;
private
   ... -- You have visibility of P's private here
end P.Q;

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



^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: OOP in Ada: Alternatives for "protected" scope
  2012-05-04 18:48   ` Felix Krause
  2012-05-04 22:00     ` Dmitry A. Kazakov
@ 2012-05-05  4:33     ` Shark8
  1 sibling, 0 replies; 12+ messages in thread
From: Shark8 @ 2012-05-05  4:33 UTC (permalink / raw)


On Friday, May 4, 2012 1:48:53 PM UTC-5, Felix Krause wrote:
>Compared to my version (with redispatching issues fixed), this
alternative enforces a weaker contract. It does not enforce the child
classes to call Do_Prologue and Do_Epilogue when implementing
Do_Something. While this fixes the problem that I cannot have an
abstract method in the private part, I think the mix-in solution you
suggested in your second post is a better way to handle this.


Couldn't you fix this by something like the following:

Type Base is tagged null record;

Procedure Do_Prolog( Object : in out Base'Class );
Procedure Do_Epilog( Object : in out Base'Class );
-- Both called defined in the body

Procedure Work( Object : in out Base ) is abstract;
Procedure Do_Work( Object : in out Base'Class );

with a body of:
Procedure Do_Work( Object : in out Base'Class ) is
begin
  Object.Do_Prolog;
  Object.Work;
  Object.Do_Epilog;
end Do_Work;

Or am I misunderstanding your intent?



^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: OOP in Ada: Alternatives for "protected" scope
  2012-05-04 22:00     ` Dmitry A. Kazakov
@ 2012-05-05  8:28       ` Felix Krause
  2012-05-05 11:53         ` Dmitry A. Kazakov
  0 siblings, 1 reply; 12+ messages in thread
From: Felix Krause @ 2012-05-05  8:28 UTC (permalink / raw)


On 2012-05-04 22:00:41 +0000, Dmitry A. Kazakov said:

> On Fri, 4 May 2012 20:48:53 +0200, Felix Krause wrote:
> 
>> On 2012-05-03 21:56:51 +0000, Dmitry A. Kazakov said:
>>> 
>>> If Do_Something varies in children they should override it. The reusable
>>> parts common for all children can be factored out as a private class-wide
>>> operation.
>> 
>> Compared to my version (with redispatching issues fixed), this
>> alternative enforces a weaker contract.
> 
> I don't like re-dispatch, it is a design bug to me.

Well, this is probably a question of personal preference. At least Ada 
lets one choose whether to redispatch or not.

> 
>>> This is exactly what Ada's private is. The correspondence goes as follows:
>>> 
>>> "Public" <-> Ada' public operation
>>> "Protected" <-> Ada's private operation
>>> "Private" <-> An operation defined in the package body
>> 
>> So, to be able to use these visibility scopes, the class hierarchy must
>> follow the layout of the package hierarchy.
> 
> That depends on what you mean. Classes (types constituting them) stretch
> across packages, as types don't live in the vacuum.
> 
> Ada separates types and visibility. Comparing to other languages it is a
> great advantage. I understand that you see it differently, but that is
> because you haven't yet accustomed to the Ada's model.

I think you're right here. I don't want to question Ada's model, I just 
want to see how it can be applied to OOP-related problems.

> Note that Ada has another (inferior) model as well. It can be seen in Ada
> protected and task types. They are mess. It was a mistake.
> 
>> I think this is a
>> disadvantage for some reasons:
>> 
>> * Given the scenario that you use an Ada software library containing
>> tagged types, you have to subclass these types in child-packages within
>> the package layout of the library.
> 
> Only if you want to access private, i.e. implementation-dependent, stuff.
> Note that when a package depends on the implementation details of another
> package, this constitutes a tight coupling. Ada requires the programmer to
> manifest this design decision in the form of a parent-child package
> relation. This IMO is a good thing. You cannot access the implementation
> details if you don't state your intention making it visible for the reader.
> Note also that this decision is all on the child's side. In the competing
> model, any derived type always get access, so the decision is on the parent
> type side. This is a bad design because it forces the programmer to make
> his choice early and, maybe, it does a wrong person.

Hmm, good point. I see "protected" / abstract methods rather as an 
additional interface of the class type than as 
"implementation-dependent stuff". While it's true that changing the 
implementation of a type by overriding its operations implies tight 
coupling, I don't think this is neccessarily true for abstract methods. 
But I see that if abstract methods are an interface of the type, these 
should rather be placed in the public part.

>> I for myself would rather want to
>> place my code in the package hierarchy of my application.
> 
> That is not a problem, you can rename packages.

Didn't think about that, good point.

>> * It doesn't work with generics:
>> 
>> generic
>> -- ...
>> package P is
>> type A is tagged private;
>> -- …
>> end P;
>> 
>> package Q is
>> package P_Instance is new P (...);
>> 
>> type B is new P_Instance.A with private;
>> end P.Q.R;
> 
> You use a generic child:
> 
> generic
> package P.Q is
>    type B is new A with private;
> private
>    ... -- You have visibility of P's private here
> end P.Q;

Yes, but that's not what I wanted. Let's have a more specific example 
using orthogonal inheritance:

package P is
   type A is tagged private;
   -- ...
end P;

generic
   type Base is new A with private;
package P.Extend is
   type Extended is new Base with private;
   -- ...
end P.Extend;

package P.Q is
   type B is new A with private;
   -- ...
end P.Q;

package P.Q.R is
   package B_Extend is new P.Extend (Base => B);
   type C is new B_Extend.Extended with private;
end P.Q.R;

(I actually have some code with this structure.) I cannot possibly 
access the private part of P.Extend in P.Q.R - although I'm extending 
the class defined there. I cannot layout the packages in a way that 
lets me access both P.Extend's and P.Q's private part in P.Q.R.

I admit that this is a rare case and in my code I don't need to share 
any private information of P.Extend.




^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: OOP in Ada: Alternatives for "protected" scope
  2012-05-05  8:28       ` Felix Krause
@ 2012-05-05 11:53         ` Dmitry A. Kazakov
  0 siblings, 0 replies; 12+ messages in thread
From: Dmitry A. Kazakov @ 2012-05-05 11:53 UTC (permalink / raw)


On Sat, 5 May 2012 10:28:43 +0200, Felix Krause wrote:

> Yes, but that's not what I wanted. Let's have a more specific example 
> using orthogonal inheritance:
> 
> package P is
>    type A is tagged private;
>    -- ...
> end P;
> 
> generic
>    type Base is new A with private;
> package P.Extend is
>    type Extended is new Base with private;
>    -- ...
> end P.Extend;
> 
> package P.Q is
>    type B is new A with private;
>    -- ...
> end P.Q;
> 
> package P.Q.R is
>    package B_Extend is new P.Extend (Base => B);
>    type C is new B_Extend.Extended with private;
> end P.Q.R;
> 
> (I actually have some code with this structure.) I cannot possibly 
> access the private part of P.Extend in P.Q.R - although I'm extending 
> the class defined there.

Extending = use. Using does not give special rights on the content! (:-))
The idea is that you create derived types in a way independent on the
implementation of the parent. If the provider of the parent hid some stuff
in the private part, there must be a good reason why nobody should look
after.

BTW, things hidden in the bodies are inaccessible by any means. My attitude
to "private" is to treat it as a compromise helping the compiler to know
what it should know, rather than a design tool to give access to children.
Ideally, the private part should contain only things which cannot be moved
to the body due to language constraints.

> I cannot layout the packages in a way that 
> lets me access both P.Extend's and P.Q's private part in P.Q.R.

Are you constructing the dreadful Rhombus? (:-))

If a package need to see internals of two packages it must be a descendant
of both. This makes it generic if one of them is.

   package P is
      type A is tagged private;
      -- ...
   end P;

   package P.Q is
   type B is new A with private;
      -- ...
   end P.Q;

   generic
      type Base is new A with private;
   package P.Q.Extend is
      type Extended is new Base with private;
      -- ...
   end P.Q.Extend;

   generic
   package P.Q.Extend.R is
      type C is new Extended with private;
   end P.Q.Extend.R;

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



^ permalink raw reply	[flat|nested] 12+ messages in thread

end of thread, other threads:[~2012-05-05 11:54 UTC | newest]

Thread overview: 12+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2012-05-03 21:27 OOP in Ada: Alternatives for "protected" scope Felix Krause
2012-05-03 21:56 ` Dmitry A. Kazakov
2012-05-04 18:48   ` Felix Krause
2012-05-04 22:00     ` Dmitry A. Kazakov
2012-05-05  8:28       ` Felix Krause
2012-05-05 11:53         ` Dmitry A. Kazakov
2012-05-05  4:33     ` Shark8
2012-05-03 23:34 ` Randy Brukardt
2012-05-04  1:41 ` BrianG
2012-05-04 10:37 ` Georg Bauhaus
2012-05-04 10:43   ` Georg Bauhaus
2012-05-04 12:10   ` Dmitry A. Kazakov

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