comp.lang.ada
 help / color / mirror / Atom feed
* Re: polymorphism
@ 1996-11-25  0:00 W. Wesley Groleau (Wes)
  0 siblings, 0 replies; 10+ messages in thread
From: W. Wesley Groleau (Wes) @ 1996-11-25  0:00 UTC (permalink / raw)



:> .... an abstract data type, denoted by the keyword "private" ....

If you must insist on a keyword for an ADT, "abstract" might be better.
But I don't go for that either.  Must we re-define abstract so that it
does not apply to most instances of abstraction?  If "abstract" is
not the opposite of "concrete", then what is the term for something
that is neither?

I consider all of the following "abstract" data types (especially as
compared with "int" and "double"):

type Radians is new Float;

type Payment is
  record
    Gross : some_money_ADT;
    FITW  : some_money_ADT;
    ....

type Months is ( January, February, ....

---------------------------------------------------------------------------
W. Wesley Groleau (Wes)                                Office: 219-429-4923
Hughes Defense Communications (MS 10-40)                 Home: 219-471-7206
Fort Wayne,  IN   46808                  (Unix): wwgrol@pseserv3.fw.hac.com
---------------------------------------------------------------------------
Object-oriented is a synonym for "great"
My favorite language is xxxx.
My favorite language is great.
Language yyyy is not xxxx.
Therefore, yyyy is not object-oriented.




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

* Polymorphism
@ 2015-05-06 23:05 slos
  2015-05-07  7:28 ` Polymorphism Simon Wright
  2015-05-07  7:41 ` Polymorphism Dmitry A. Kazakov
  0 siblings, 2 replies; 10+ messages in thread
From: slos @ 2015-05-06 23:05 UTC (permalink / raw)


Hello,

Please consider the following simple case :

package Object is
   
   type Instance is abstract tagged private;
   
   function Distance (O : Instance'Class) return Float;
   
   function Weight (O : Instance'Class; Coef : Float) return Float;
   --  returns Area * Coef
   
   function Area (O : Instance) return Float is abstract;
   
private
   
   type Instance is abstract tagged
      record
         X_Coord : Float;
         Y_Coord : Float;
      end record;
   
end Object;

with Object; use Object;

package Circle is

   type Instance is new Object.Instance with private;

private

   type Instance is new Object.Instance with
      record
         Radius : Float;
      end record;

   overriding
   function Area (C : Instance) return Float;

end Circle;

I'd like function Object.Area to stay private but the compiler doesn't see it like that and complains if I try to move it in the private part.

In other words, I'd like to not expose internals to clients of the package.

Any hint to achieve that ?

Thanks in advance.

BR,
Stéphane

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

* Re: Polymorphism
  2015-05-06 23:05 Polymorphism slos
@ 2015-05-07  7:28 ` Simon Wright
  2015-05-07  8:32   ` Polymorphism slos
  2015-05-07  7:41 ` Polymorphism Dmitry A. Kazakov
  1 sibling, 1 reply; 10+ messages in thread
From: Simon Wright @ 2015-05-07  7:28 UTC (permalink / raw)


slos <new.stephane.los@gmail.com> writes:

> I'd like function Object.Area to stay private but the compiler doesn't
> see it like that and complains if I try to move it in the private
> part.

If you do that, the compiler says

slos.ada:24:13: this primitive operation is declared too late
slos.ada:24:13: abstract subprograms must be visible (RM 3.9.3(10))

The reason for this is that derived types wouldn't know that they needed
to implement the abstract operations.

If you make the private subprogram concrete,

   function Area (O : Instance) return Float
     is (raise Program_Error with "Area not implemented");

then Circle.Area isn't overriding (because Object.Area isn't visible).

If you make Circle a child of Object (package Object.Circle), all is
OK. This is of curse rather restrictive; it depends on who you want to
be able to derive from Object.Instance.


The workround I adopted in a similar situation was to comment the
subprograms that had to be visible with "private use only". I think now
I would make the names obviously logically private
(e.g. "Private_Area").


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

* Re: Polymorphism
  2015-05-06 23:05 Polymorphism slos
  2015-05-07  7:28 ` Polymorphism Simon Wright
@ 2015-05-07  7:41 ` Dmitry A. Kazakov
  2015-05-07  8:34   ` Polymorphism slos
  2015-05-07 19:09   ` Polymorphism Randy Brukardt
  1 sibling, 2 replies; 10+ messages in thread
From: Dmitry A. Kazakov @ 2015-05-07  7:41 UTC (permalink / raw)


On Wed, 6 May 2015 16:05:28 -0700 (PDT), slos wrote:

> Please consider the following simple case :
> 
> package Object is
[...]    
> end Circle;
> 
> I'd like function Object.Area to stay private but the compiler doesn't see
> it like that and complains if I try to move it in the private part.
> 
> In other words, I'd like to not expose internals to clients of the package.
> 
> Any hint to achieve that ?

If you privately override anything for something that is publicly
dynamically polymorphic [~tagged], then that is not any private because you
can [and must] be able to call the overriding body.

The Ada's types model is that Circle.Instance has the function Area anyway.
It is either implemented per inheritance of the parent's type
implementation (if exists) or by providing a new body per overriding. Thus
moving overriding into private changes nothing.

I don't know why it is not allowed. Moreover, it probably would make sense
to move all declarations of overriding into private or even further into
the package body because the fact of overriding is mere an implementation
detail, since the primitive subroutine is there anyway no matter what.

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


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

* Re: Polymorphism
  2015-05-07  7:28 ` Polymorphism Simon Wright
@ 2015-05-07  8:32   ` slos
  0 siblings, 0 replies; 10+ messages in thread
From: slos @ 2015-05-07  8:32 UTC (permalink / raw)


Le jeudi 7 mai 2015 09:28:46 UTC+2, Simon Wright a écrit :
> slos writes:
> 
> > I'd like function Object.Area to stay private but the compiler doesn't
> > see it like that and complains if I try to move it in the private
> > part.
> 
> If you do that, the compiler says
> 
> slos.ada:24:13: this primitive operation is declared too late
> slos.ada:24:13: abstract subprograms must be visible (RM 3.9.3(10))
> 
> The reason for this is that derived types wouldn't know that they needed
> to implement the abstract operations.
> 
> If you make the private subprogram concrete,
> 
>    function Area (O : Instance) return Float
>      is (raise Program_Error with "Area not implemented");
> 
> then Circle.Area isn't overriding (because Object.Area isn't visible).
> 
> If you make Circle a child of Object (package Object.Circle), all is
> OK. This is of curse rather restrictive; it depends on who you want to
> be able to derive from Object.Instance.
> 
> 
> The workround I adopted in a similar situation was to comment the
> subprograms that had to be visible with "private use only". I think now
> I would make the names obviously logically private
> (e.g. "Private_Area").

Thank you for your answer Simon.

I have found this suitable for my needs :

> If you make Circle a child of Object (package Object.Circle), all is
> OK. This is of curse rather restrictive; it depends on who you want to
> be able to derive from Object.Instance.

But I thought about something like a private inner package or interface may have existed.

BR,
Stéphane


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

* Re: Polymorphism
  2015-05-07  7:41 ` Polymorphism Dmitry A. Kazakov
@ 2015-05-07  8:34   ` slos
  2015-05-07 19:09   ` Polymorphism Randy Brukardt
  1 sibling, 0 replies; 10+ messages in thread
From: slos @ 2015-05-07  8:34 UTC (permalink / raw)


Le jeudi 7 mai 2015 09:41:55 UTC+2, Dmitry A. Kazakov a écrit :
> On Wed, 6 May 2015 16:05:28 -0700 (PDT), slos wrote:
> 
> > Please consider the following simple case :
> > 
> > package Object is
> [...]    
> > end Circle;
> > 
> > I'd like function Object.Area to stay private but the compiler doesn't see
> > it like that and complains if I try to move it in the private part.
> > 
> > In other words, I'd like to not expose internals to clients of the package.
> > 
> > Any hint to achieve that ?
> 
> If you privately override anything for something that is publicly
> dynamically polymorphic [~tagged], then that is not any private because you
> can [and must] be able to call the overriding body.
> 
> The Ada's types model is that Circle.Instance has the function Area anyway.
> It is either implemented per inheritance of the parent's type
> implementation (if exists) or by providing a new body per overriding. Thus
> moving overriding into private changes nothing.
> 
> I don't know why it is not allowed. Moreover, it probably would make sense
> to move all declarations of overriding into private or even further into
> the package body because the fact of overriding is mere an implementation
> detail, since the primitive subroutine is there anyway no matter what.
> 
> -- 
> Regards,
> Dmitry A. Kazakov
> http://www.dmitry-kazakov.de

Thank you Dmitry for your answer.

BR,
Stéphane

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

* Re: Polymorphism
  2015-05-07  7:41 ` Polymorphism Dmitry A. Kazakov
  2015-05-07  8:34   ` Polymorphism slos
@ 2015-05-07 19:09   ` Randy Brukardt
  2015-05-11 22:05     ` Polymorphism slos
  1 sibling, 1 reply; 10+ messages in thread
From: Randy Brukardt @ 2015-05-07 19:09 UTC (permalink / raw)


"Dmitry A. Kazakov" <mailbox@dmitry-kazakov.de> wrote in message 
news:5hbl45anxasb.1jn73i00zgy2i.dlg@40tude.net...
...
> I don't know why it is not allowed.

It *is* allowed. The problem in the OPs case is that the routine was 
abstract. Abstract routines must be overridden, but if it is private a 
client can't know that. Moreover, a client *cannot* override a private 
operation, so there could be no client in that case. Thus the original 
declaration is illegal.

As Simon pointed out, if the operation is concrete, it is fine to put it 
there. Then all clients that need to override it have to be child packages. 
Claw uses this extensively.

> Moreover, it probably would make sense
> to move all declarations of overriding into private

This is my coding standard. I only put new stuff into the visible part.

> or even further into the package body

That's not allowed as the tag has to be known when the type is frozen (that 
is, at the end of the specification). Of course, it would be possible to 
have a different set of rules where the tag isn't known at that point, but 
that's not the Ada design.

> because the fact of overriding is mere an implementation
> detail, since the primitive subroutine is there anyway no matter what.

Correct; that's why I put them into the private part.

                               Randy. 


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

* Re: Polymorphism
  2015-05-07 19:09   ` Polymorphism Randy Brukardt
@ 2015-05-11 22:05     ` slos
  2015-05-12  1:29       ` Polymorphism Randy Brukardt
  0 siblings, 1 reply; 10+ messages in thread
From: slos @ 2015-05-11 22:05 UTC (permalink / raw)


Le jeudi 7 mai 2015 21:09:33 UTC+2, Randy Brukardt a écrit :
> "Dmitry A. Kazakov"  wrote in message 
> news:...
> ...
> > I don't know why it is not allowed.
> 
> It *is* allowed. The problem in the OPs case is that the routine was 
> abstract. Abstract routines must be overridden, but if it is private a 
> client can't know that. Moreover, a client *cannot* override a private 
> operation, so there could be no client in that case. Thus the original 
> declaration is illegal.
> 
> As Simon pointed out, if the operation is concrete, it is fine to put it 
> there. Then all clients that need to override it have to be child packages. 
> Claw uses this extensively.
> 
> > Moreover, it probably would make sense
> > to move all declarations of overriding into private
> 
> This is my coding standard. I only put new stuff into the visible part.
> 
> > or even further into the package body
> 
> That's not allowed as the tag has to be known when the type is frozen (that 
> is, at the end of the specification). Of course, it would be possible to 
> have a different set of rules where the tag isn't known at that point, but 
> that's not the Ada design.
> 
> > because the fact of overriding is mere an implementation
> > detail, since the primitive subroutine is there anyway no matter what.
> 
> Correct; that's why I put them into the private part.
> 
>                                Randy.

Thank you Randy for your detailed information.

I have corrected my code according to the suggestions found here but I still think that there is maybe something to improve here.

If I remember correctly, I should have verified before posting but it's already late, in C++ one can have protected members which can be used by friends.
I can't see in Ada such thing like protected stuff and friends. Maybe there is ?

Indeed I was looking for something like that.

The client of my root class do not need to have access to those helping methods that have to be implemented by the derived ones.

I am quite happy with the child package solution exposed here by Simon but then that has disturbed my packages hierarchy... ;-)

I had grouped my derived classes by field bus technology, one package for PROFIBUS, another for EtherCAT and so on.

Since the root class, implementing an acyclic request, is independent on the field bus technology, I had had a "with" clause to my derived requests and it was working fine, excepted that my abstract methods had to be public.

So it ends up with two related hierarchies, one descending from the root acyclic request and the derived requests grouped by technology, and another hierarchy holding types, constants, etc... that can be useful also for other stuff like status, indications...

But again, I am fine with that solution if there is no smarter way.

BR,
Stéphane
http://slo-ist.fr/ada4autom


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

* Re: Polymorphism
  2015-05-11 22:05     ` Polymorphism slos
@ 2015-05-12  1:29       ` Randy Brukardt
  2015-05-14 21:34         ` Polymorphism slos
  0 siblings, 1 reply; 10+ messages in thread
From: Randy Brukardt @ 2015-05-12  1:29 UTC (permalink / raw)


[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #1: Type: text/plain, Size: 1123 bytes --]

"slos" <new.stephane.los@gmail.com> wrote in message 
news:d0b830a1-19c8-462e-b1c8-a2b19e470674@googlegroups.com...
Le jeudi 7 mai 2015 21:09:33 UTC+2, Randy Brukardt a écrit :
...
> If I remember correctly, I should have verified before posting but it's 
> already
> late, in C++ one can have protected members which can be used by friends.
> I can't see in Ada such thing like protected stuff and friends. Maybe 
> there is ?

Ada uses child packages for that sort of functionality; to be a "friend" in 
Ada, a package has to be a child. Often, a parent and set of children is 
referred to as a "subsystem". [Private packages also can be part of a 
subsystem, that's where they're useful.] Unrestricted use of friends 
appeared to lead to madness (at a minimum, visibility madness), where 
dependencies go all which ways. Ada limits such dependencies to a single 
subsystem. (Generally, one wants to minimize dependences.)

...
>I am quite happy with the child package solution exposed here by Simon
>but then that has disturbed my packages hierarchy... ;-)

Yup. There's no free lunch. ;-)

                     Randy.


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

* Re: Polymorphism
  2015-05-12  1:29       ` Polymorphism Randy Brukardt
@ 2015-05-14 21:34         ` slos
  0 siblings, 0 replies; 10+ messages in thread
From: slos @ 2015-05-14 21:34 UTC (permalink / raw)


Le mardi 12 mai 2015 03:29:50 UTC+2, Randy Brukardt a écrit :
> "slos" wrote in message 
> news:...
> Le jeudi 7 mai 2015 21:09:33 UTC+2, Randy Brukardt a écrit :
> ...
> > If I remember correctly, I should have verified before posting but it's 
> > already
> > late, in C++ one can have protected members which can be used by friends.
> > I can't see in Ada such thing like protected stuff and friends. Maybe 
> > there is ?
> 
> Ada uses child packages for that sort of functionality; to be a "friend" in 
> Ada, a package has to be a child. Often, a parent and set of children is 
> referred to as a "subsystem". [Private packages also can be part of a 
> subsystem, that's where they're useful.] Unrestricted use of friends 
> appeared to lead to madness (at a minimum, visibility madness), where 
> dependencies go all which ways. Ada limits such dependencies to a single 
> subsystem. (Generally, one wants to minimize dependences.)
> 
> ...
> >I am quite happy with the child package solution exposed here by Simon
> >but then that has disturbed my packages hierarchy... ;-)
> 
> Yup. There's no free lunch. ;-)
> 
>                      Randy.

Hello Randy,

Thanks for your detailed information.
In fact, I am very happy with the solution and it ends up quite understandable, from my point of view...

Since derived objects are children of their parent class, it seems logical that the packages where they are defined are also children of those where their parent is.

That's only necessary if needed to access private attributes and methods but it is maybe a good idea to do so in most cases since the package hierarchy then mimics the objects hierarchy, isn't it ?

Best Regards,
Stéphane
http://slo-ist.fr/ada4autom

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

end of thread, other threads:[~2015-05-14 21:34 UTC | newest]

Thread overview: 10+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2015-05-06 23:05 Polymorphism slos
2015-05-07  7:28 ` Polymorphism Simon Wright
2015-05-07  8:32   ` Polymorphism slos
2015-05-07  7:41 ` Polymorphism Dmitry A. Kazakov
2015-05-07  8:34   ` Polymorphism slos
2015-05-07 19:09   ` Polymorphism Randy Brukardt
2015-05-11 22:05     ` Polymorphism slos
2015-05-12  1:29       ` Polymorphism Randy Brukardt
2015-05-14 21:34         ` Polymorphism slos
  -- strict thread matches above, loose matches on Subject: below --
1996-11-25  0:00 polymorphism W. Wesley Groleau (Wes)

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