comp.lang.ada
 help / color / mirror / Atom feed
* Barnes vs. Dewar
@ 1999-08-27  0:00 Anton Gibbs
  1999-08-27  0:00 ` Robert A Duff
                   ` (2 more replies)
  0 siblings, 3 replies; 6+ messages in thread
From: Anton Gibbs @ 1999-08-27  0:00 UTC (permalink / raw)


Dear Ada Experts,

     Here is an interesting one based on Chapter 13.7 (Controlled Types)
from John Barnes' book Programming in Ada 95.

Although the subject under discussion is controlled types, the author
takes the opportunity to illustrate the use of type extension as a means
of limiting the user view of a type. The relevant code fragment is:-

package Tracked_Things is

   type Identity_Controlled is abstract tagged private;

private

   type Identity_Controlled is abstract new Controlled with
   record
      Identity_Number : Integer;
   end record;

   procedure Initialize( X : in Identity_Controlled );
   -- etc.

end Tracked_Things;

package Tracked_Things.User_View is
 
   type Thing is new Identity_Controlled with
   record
      UU : Integer;
   end record;

end Tracked_Things.User_View;

[There are few with/use clauses implied here].


Page 287, third paragraph from the end, last sentance reads:

   "We also declare Initialize, Adjust and Finalize in the private part
and so they are also hidden from the user."

Clearly, these operations are expected to be inherited for the extended
type `Thing' in child package `Tracked_Things.User_View'.

Well, when I tried a similar thing with the GNAT compiler it threw it
out complaining that:

   "Initialize" is not a visible entity of "User_View"

After the usual agony with the LRM, I eventually had to agree. I do not
think that the child package `Tracked_Things.User_View' is entitled to
see `Initialize' in the private part of its parent and so it cannot be
inherited. If you move `Initialize' to the visible part it all works
fine.

So who is right Barnes or Dewar ?

More to the point, what is the correct way to achieve the desired level
of visibility (ie. `Tracked_Things.User_View.Initialize' visible
but `Tracked_Things.Initialize' not) ?

Thanks for any clues.

Best -- Anton.

--
Anton Gibbs
Software Engineer
Civil Air Traffic Management Group
Defence Evaluation and Research Agency
Bedford, UK

"The Information contained in this E-Mail and any 
subsequent correspondence is private and is intended
solely for the intended recipient(s).  For those
other than the intended recipient any disclosure,
copying, distribution, or any action taken or 
omitted to be taken in reliance on such information
is prohibited and may be unlawful."




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

* Re: Barnes vs. Dewar
  1999-08-27  0:00 Barnes vs. Dewar Anton Gibbs
  1999-08-27  0:00 ` Robert A Duff
@ 1999-08-27  0:00 ` Matthew Heaney
  1999-08-29  0:00 ` Robert Dewar
  2 siblings, 0 replies; 6+ messages in thread
From: Matthew Heaney @ 1999-08-27  0:00 UTC (permalink / raw)


In article <37C66E08.16DB@dera.gov.uk> , Anton Gibbs <agibbs@dera.gov.uk> 
wrote:

> package Tracked_Things is
>
>    type Identity_Controlled is abstract tagged private;
>
> private
>
>    type Identity_Controlled is abstract new Controlled with
>    record
>       Identity_Number : Integer;
>    end record;
>
>    procedure Initialize( X : in Identity_Controlled );
>    -- etc.
>
> end Tracked_Things;
>
> package Tracked_Things.User_View is
>
>    type Thing is new Identity_Controlled with
>    record
>       UU : Integer;
>    end record;
>
> end Tracked_Things.User_View;
>
> [There are few with/use clauses implied here].
>
> Page 287, third paragraph from the end, last sentance reads:
>
>    "We also declare Initialize, Adjust and Finalize in the private part
> and so they are also hidden from the user."

That is the proper thing to do.  Controlled-ness for a type should be
completely hidden from clients.

> Clearly, these operations are expected to be inherited for the extended
> type `Thing' in child package `Tracked_Things.User_View'.

Yes, they are indeed inherited, but only for a private view.  A private view
of Thing is

o the body of Tracked_Thing.User_View

o anywhere in a private child of Tracked_Thing.User_View

o the private part of the spec of a public child of Tracked_Thing.User_View,
and its body


> Well, when I tried a similar thing with the GNAT compiler it threw it
> out complaining that:
>
>    "Initialize" is not a visible entity of "User_View"


But, are you sure you didn't try to do this:

  with Tracked_Thing.User_View;  use Tracked_Thing.User_View;
  procedure Op is
    O : Thing;
  begin
    Initialize (O);
  end Op;

This is of course illegal, because Op isn't a private view of Thing.

Try this instead:

  private procedure Tracked_Thing.User_View.Op;

  procedure Tracked_Thing.User_View.Op is
    O : Thing;
  begin
    Initialize (O);
  end;

This should work, but I don't have a compiler handy to test it.

> After the usual agony with the LRM, I eventually had to agree. I do not
> think that the child package `Tracked_Things.User_View' is entitled to
> see `Initialize' in the private part of its parent and so it cannot be
> inherited. If you move `Initialize' to the visible part it all works
> fine.

Not quite right.  Only the public part of Tracked_Things.User_View is not
allowed to see Initialize.  The operations Init, Final, and Adj are indeed
inherited, and you can see them in the private part of the spec of
Tracked_Things.User_View, and in its body.

Try this:

package Tracked_Things.User_View is

  type Thing is new Identity_Controlled with
  record
    UU : Integer;
  end record;

private

  procedure Initialize (O : in out Thing);  -- override; should compile OK

end Tracked_Things.User_View;

or try this:

<original spec of Tracked_Things.User_View>

package body Tracked_Things.User_View is
  O : Thing;
begin
  Initialize (O);  -- visible, because body is a private view
end;

> So who is right Barnes or Dewar ?

Barnes is right.  If you tried to call Initialize from a public view, then
Dewar is also correct.

> More to the point, what is the correct way to achieve the desired level
> of visibility (ie. `Tracked_Things.User_View.Initialize' visible
> but `Tracked_Things.Initialize' not) ?

This doesn't make any sense.  The operation Initialize is private for ALL
types in the class whose root is Identity_Controlled, including Thing.  You
can NEVER call Initialize (Object_Of_Type_Thing) from a public view.

> Thanks for any clues.

If you want to have a public operation for Thing that does some kind of
initialization (maybe even implement it by calling the controlled operation
called Initialize), then you're going to have to give the operation some
other name.

package Tracked_Things.User_View is

  type Thing is new Identity_Controlled with
  record
    UU : Integer;
  end record;

  procedure Reset (O : in out Thing);

end Tracked_Things.User_View;


package body Tracked_Things.User_View is

  procedure Reset (O : in out Thing) is
  begin
    Initialize (O);  -- should be legal
  end;

end Tracked_Things.User_View;


--
Matt

It is impossible to feel great confidence in a negative theory which has
always rested its main support on the weak points of its opponent.

Joseph Needham, "A Mechanistic Criticism of Vitalism"




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

* Re: Barnes vs. Dewar
  1999-08-27  0:00 Barnes vs. Dewar Anton Gibbs
@ 1999-08-27  0:00 ` Robert A Duff
  1999-08-27  0:00   ` Matthew Heaney
  1999-08-27  0:00 ` Matthew Heaney
  1999-08-29  0:00 ` Robert Dewar
  2 siblings, 1 reply; 6+ messages in thread
From: Robert A Duff @ 1999-08-27  0:00 UTC (permalink / raw)


Anton Gibbs <agibbs@dera.gov.uk> writes:

> Well, when I tried a similar thing with the GNAT compiler it threw it
> out complaining that:
> 
>    "Initialize" is not a visible entity of "User_View"
> 
> After the usual agony with the LRM, I eventually had to agree. I do not
> think that the child package `Tracked_Things.User_View' is entitled to
> see `Initialize' in the private part of its parent and so it cannot be
> inherited. If you move `Initialize' to the visible part it all works
> fine.
> 
> So who is right Barnes or Dewar ?

You'll have to post the exact code you compiled, along with the error
message, to know whether Barnes or gnat or both are correct.  "A similar
thing" isn't specific enough.

By the way, Dewar isn't *exactly* synonymous with gnat.  ;-) ;-)

> More to the point, what is the correct way to achieve the desired level
> of visibility (ie. `Tracked_Things.User_View.Initialize' visible
> but `Tracked_Things.Initialize' not) ?

You may declare Initialize in the visible part of
Tracked_Things.User_View, and it will override the privately-inherited
Initialize, and it will also be visible outside this package.
Is that what you want?

- Bob
-- 
Change robert to bob to get my real email address.  Sorry.




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

* Re: Barnes vs. Dewar
  1999-08-27  0:00 ` Robert A Duff
@ 1999-08-27  0:00   ` Matthew Heaney
  1999-08-30  0:00     ` Robert A Duff
  0 siblings, 1 reply; 6+ messages in thread
From: Matthew Heaney @ 1999-08-27  0:00 UTC (permalink / raw)


In article <wcc3dx5gp7v.fsf@world.std.com> , Robert A Duff 
<bobduff@world.std.com>  wrote:

> You may declare Initialize in the visible part of
> Tracked_Things.User_View, and it will override the privately-inherited
> Initialize, and it will also be visible outside this package.

Wow!  I didn't know you could do that.  I just assumed that once private,
then always private, for all descendents.

> Is that what you want?

Good question.  It's bad enough that a controlled operation is public, but
it's even worse when public-ness only applies to some types in the class.

--
Matt

It is impossible to feel great confidence in a negative theory which has
always rested its main support on the weak points of its opponent.

Joseph Needham, "A Mechanistic Criticism of Vitalism"




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

* Re: Barnes vs. Dewar
  1999-08-27  0:00 Barnes vs. Dewar Anton Gibbs
  1999-08-27  0:00 ` Robert A Duff
  1999-08-27  0:00 ` Matthew Heaney
@ 1999-08-29  0:00 ` Robert Dewar
  2 siblings, 0 replies; 6+ messages in thread
From: Robert Dewar @ 1999-08-29  0:00 UTC (permalink / raw)


In article <37C66E08.16DB@dera.gov.uk>,
  Anton Gibbs <agibbs@dera.gov.uk> wrote:
> So who is right Barnes or Dewar ?
                            ^^^^^
you mean GNAT! Please do not assume that Dewar knows
everything about GNAT :-)




Sent via Deja.com http://www.deja.com/
Share what you know. Learn what you don't.




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

* Re: Barnes vs. Dewar
  1999-08-27  0:00   ` Matthew Heaney
@ 1999-08-30  0:00     ` Robert A Duff
  0 siblings, 0 replies; 6+ messages in thread
From: Robert A Duff @ 1999-08-30  0:00 UTC (permalink / raw)


"Matthew Heaney" <matthew_heaney@acm.org> writes:

> Wow!  I didn't know you could do that.  I just assumed that once private,
> then always private, for all descendents.

Take a look at 7.3.1.  Remember we're talking about a derived type in a
child package here -- when we get to the private part, all kinds of
information about the parent type become magically revealed.  In
particular, we inherit a subprogram.

Now, given that there's an explicit subprogram with the same name and
parameter types, what can we do?  Making it override the implicit one is
really the only sensible answer.

> Good question.  It's bad enough that a controlled operation is public, but
> it's even worse when public-ness only applies to some types in the class.

I don't think it's so horrible.  There might be cases where you want to
call Initialize or Finalize explicitly, so you want to make them public.
And that might apply only to one sub-hierarchy.  So you get the choice
of deriving publicly or privately from Controlled.  Shrug.

Note that if you derive publicly from Controlled, the operations are
visible outside the package, whether or not you overrode them, and
whether or not you put the overridings in the private part.  I think my
previous message might have been misleading on that point...

- Bob
-- 
Change robert to bob to get my real email address.  Sorry.




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

end of thread, other threads:[~1999-08-30  0:00 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
1999-08-27  0:00 Barnes vs. Dewar Anton Gibbs
1999-08-27  0:00 ` Robert A Duff
1999-08-27  0:00   ` Matthew Heaney
1999-08-30  0:00     ` Robert A Duff
1999-08-27  0:00 ` Matthew Heaney
1999-08-29  0:00 ` Robert Dewar

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