comp.lang.ada
 help / color / mirror / Atom feed
* Please explain why this is wrong...
@ 1995-02-07 23:01 Jim Rogers
  1995-02-09  3:55 ` Robert Dewar
       [not found] ` <3hjj97$dld@gnat.cs.nyu.edu>
  0 siblings, 2 replies; 4+ messages in thread
From: Jim Rogers @ 1995-02-07 23:01 UTC (permalink / raw)


I have been playing with simple inheritance models.  When I try to declare
a type as:

  type Cube is new Square with null record;

I get the following message from the gnatf tool:

shapes.ads:87:09: type must be declared abstract or else "new_square" overriden

Why do I get this message.  I think I am using the same syntax I read in the
Instr.ads file found in the GNAT examples directory.

The source for my code follows:

-- file shapes.ads
-----------------------------------------------------------------------------
-- Experimenting with the simple designs of Ada shapes classes
-----------------------------------------------------------------------------

with Ada.Numerics.Aux;
use  Ada.Numerics.Aux;

package shapes is

-----------------------------------------------------------------------------
-- Abstract definition for shape
-----------------------------------------------------------------------------
   
   type shape is abstract tagged private;

   function area( Object : shape) return double is abstract;

   function get_name( Object : shape ) return string is abstract;

-----------------------------------------------------------------------------
-- Definition of rectangle as an inheritor of shape
-----------------------------------------------------------------------------

   type rectangle is new shape with private;

   function new_rectangle( height : double; width : double ) return rectangle;

   function area ( Object : rectangle ) return double;

   function get_name (Object : rectangle ) return string;


-----------------------------------------------------------------------------
-- Definition of circle as an inheritor of shape
-----------------------------------------------------------------------------

   type circle is new shape with private;

   function new_circle( Radius : double ) return circle;

   function area ( Object : circle ) return double;

   function get_name ( Object : circle ) return string;


-----------------------------------------------------------------------------
-- Definition of square as an inheritor of rectangle
-----------------------------------------------------------------------------

   type square is new shape with private;

   function new_square ( Side : double ) return square;

   function area ( Object : square ) return double;

   function get_name ( Object : square ) return string;

-----------------------------------------------------------------------------
-- Definition of square as an inheritor of rectangle
-----------------------------------------------------------------------------

   type cube is new square with private;

   function new_cube (Side : double) return cube;

   function volume ( Object : cube ) return double;

   function get_name ( Object : cube ) return string;

private

   type shape is tagged null record;

   type rectangle is new shape with record
      height : double := 0.0;
      width  : double := 0.0;
   end record;

   type circle is new shape with record
      radius : double := 0.0;
   end record;

   type square is new shape with record
      side   : double := 0.0;
   end record;

   type cube is new square with null record;

end shapes;


-- file shapes.adb
with Ada.Numerics.Aux;
use  Ada.Numerics.Aux;

package body shapes is

   function new_rectangle( height : double; width : double ) return rectangle is
      tmp : rectangle;
   begin
      tmp.height := height;
      tmp.width  := width;
      return tmp;
   end new_rectangle;

   function area ( Object : rectangle ) return double is
   begin
      return Object.height * Object.width;
   end area;

   function get_name (Object : rectangle ) return string is
   begin
      return "rectangle";
   end get_name;


   function new_circle( Radius : double ) return circle is
      tmp : circle;
   begin
      tmp.radius := radius;
      return tmp;
   end new_circle;

   function area ( Object : circle ) return double is
   begin
      return double(3.14159) * Object.radius * Object.radius;
   end area;

   function get_name ( Object : circle ) return string is
   begin
      return "circle";
   end get_name;


   function new_square ( Side : double ) return square is
      tmp : square;
   begin
      tmp.side := side;
      return tmp;
   end new_square;

   function area ( Object : square ) return double is
   begin
      return Object.side * Object.side;
   end area;

   function get_name ( Object : square ) return string is
   begin
      return "square";
   end get_name;


   function new_cube ( Side : double ) return cube is
      tmp : cube;
   begin
      tmp.side := side;
      return tmp;
   end new_cube;

   function volume ( Object : cube ) return double is
      S : double := Object.side;
   begin
      return S * S * S;
   end volume;

   function get_name ( Object : cube ) return string is
   begin
      return "cube";
   end get_name;

end shapes;


--
------------------------------------------------------------------------------
| Jim Rogers                    | Dead Reckoning:                            |
| Hewlett-Packard Company       | Traditional form of rough-estimate         |
| Colorado Springs Division     | navigation used for hundreds of years by   |
|                               | sailors, almost all of whom are dead.      |
| jimr@col.hp.com               |                                            |
------------------------------------------------------------------------------



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

* Re: Please explain why this is wrong...
  1995-02-07 23:01 Please explain why this is wrong Jim Rogers
@ 1995-02-09  3:55 ` Robert Dewar
  1995-02-10  5:19   ` Jim Rogers
       [not found] ` <3hjj97$dld@gnat.cs.nyu.edu>
  1 sibling, 1 reply; 4+ messages in thread
From: Robert Dewar @ 1995-02-09  3:55 UTC (permalink / raw)


Your program is clearly wrong, and the message from GNAT is quite precise.

You have a primitive operation New_Square, which is inherited when you
make a rectangle to give a function New_Square that returns a Rectangle.

Now it is not clear why you made this a primitive operation. I rather suspect
that you expect to use New_Square only for a Square, in which case it should
NOT be primitive.

If indeed you intend it to be inherited, it MUST be overridden. The reason
for this rule is simple. In the general case the derivation involves extending
the type, and how could the original function code possibly know enough to
initialize the extension -- it couldn't.

If as I suspect, you really did not intend New_Square to be inherited, but
rather intended it to serve as a constructor only for the Square case, then
you must be sure that you do not declare in as being primitive. The easiest
way to declare non-primitive operations is to nest them in a subpackages;

   package Constructors is
      function New_Square .. return Square;
   end Constructors;




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

* Re: Please explain why this is wrong...
  1995-02-09  3:55 ` Robert Dewar
@ 1995-02-10  5:19   ` Jim Rogers
  0 siblings, 0 replies; 4+ messages in thread
From: Jim Rogers @ 1995-02-10  5:19 UTC (permalink / raw)


Robert Dewar (dewar@cs.nyu.edu) wrote:
: Your program is clearly wrong, and the message from GNAT is quite precise.

Yes, you are correct.  I have learned, thanks to the kind expalnations from
Mssrs Dewar and Nebbe, esxactly how my thinking erred.

: You have a primitive operation New_Square, which is inherited when you
: make a rectangle to give a function New_Square that returns a Rectangle.

This is precisely what I overlooked.  I was attempting to translate a
rather trivial C++ inheritence example into Ada.  I ignored (and was
ignorant of) the inherited constructor.

:............
: If as I suspect, you really did not intend New_Square to be inherited, but
: rather intended it to serve as a constructor only for the Square case, then
: you must be sure that you do not declare in as being primitive. The easiest
: way to declare non-primitive operations is to nest them in a subpackages;

:    package Constructors is
:       function New_Square .. return Square;
:    end Constructors;

This solution was so simple and obvious that I would probably have missed it
for quite a while.  As you have already guessed, I am sure, I am not 
exactly an Ada wizard....yet.

I hope this thread has served as a good example of the problems explained by
Tucker Taft concerning Ada constructors in this same news group.

Thank you all.  I have learned yet again why I prefer Ada to C++.

--
------------------------------------------------------------------------------
| Jim Rogers                    | Dead Reckoning:                            |
| Hewlett-Packard Company       | Traditional form of rough-estimate         |
| Colorado Springs Division     | navigation used for hundreds of years by   |
|                               | sailors, almost all of whom are dead.      |
| jimr@col.hp.com               |                                            |
------------------------------------------------------------------------------



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

* Re: Please explain why this is wrong...
       [not found]     ` <3i3p2q$j7o@gnat.cs.nyu.edu>
@ 1995-02-28  3:54       ` Erik Magnuson
  0 siblings, 0 replies; 4+ messages in thread
From: Erik Magnuson @ 1995-02-28  3:54 UTC (permalink / raw)


In article <3i3p2q$j7o@gnat.cs.nyu.edu>, Robert Dewar <dewar@cs.nyu.edu> wrote:
>norman, error messages are NOT for the purposes of learning fine points
>It is easy, especially for experts in the language, to make the mistake
>of knowing too much in figuring out error messages. It is a tricky business.
>In particular, one has to be very careful not to overuse reference manual
>jargon which is unlikely to be familiar to most Ada programmers.

This comment immediately brings to mind Rational's (first Delta and it's still
in Apex) "co-resident homograph" error message when you have two procedures
with the same parameter profile.  Sometimes I think they leave it in for
the fun of it.



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

end of thread, other threads:[~1995-02-28  3:54 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
1995-02-07 23:01 Please explain why this is wrong Jim Rogers
1995-02-09  3:55 ` Robert Dewar
1995-02-10  5:19   ` Jim Rogers
     [not found] ` <3hjj97$dld@gnat.cs.nyu.edu>
     [not found]   ` <3hnquq$j2k@watnews1.watson.ibm.com>
     [not found]     ` <3i3p2q$j7o@gnat.cs.nyu.edu>
1995-02-28  3:54       ` Erik Magnuson

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