From: Bryan on
I'm new to the OOP features of Ada and I'm trying to wrap my head
tagged types. I've been reading the somewhat abstruse "Ada for
Software Engineers" and while I understand the examples in the text, I
would like to experiment on my own to further my understand. I'm
trying to figure out how I can correctly--pardon my C++--"subclass" a
base class to create a new derived "class". I created two simple
packges as follows:

parent.ads:

with Ada.Strings.Unbounded; use Ada.Strings.Unbounded;
package Parent is
type Parent is abstract tagged private;
private
type Parent is abstract tagged
record
Name: Unbounded_String;
end record;
end Parent;

derived.ads:

with Parent; use Parent;
package Derived is
type Derived is new Parent with private;
private
type Derived is new Parent with
record
Sub_Name: Unbounded_String;
end record;
end Derived;

I can compile parent.ads and the object file and ALI file are
produced. I'm unable to get derived.ads to compile, however. I get
the following error:

$ gnatmake -c parent derived.ads
gcc -c derived.ads
derived.ads:3:23: subtype mark required in this context
derived.ads:3:23: found "Parent" declared at parent.ads:2
derived.ads:5:23: subtype mark required in this context
derived.ads:5:23: found "Parent" declared at parent.ads:2
gnatmake: "derived.ads" compilation error

If I make the Derived type in a child package of the parent package, I
can get both interfaces to compile. Perhaps I am misunderstanding
something about Ada OOP, but is it possible to have a derived package
that is not a child package of the base? Must I use a child package,
or keep the derived type in the same package as the base type?
From: Hibou57 (Yannick Duchêne) on
On 9 fév, 03:16, Bryan <brobinson....(a)gmail.com> wrote:
> I created two simple
> packges as follows:
>
> parent.ads:
>
> with Ada.Strings.Unbounded; use Ada.Strings.Unbounded;
> package Parent is
>   type Parent is abstract tagged private;
> private
>   type Parent is abstract tagged
>     record
>       Name: Unbounded_String;
>     end record;
> end Parent;
>
> derived.ads:
>
> with Parent; use Parent;
> package Derived is
>   type Derived is new Parent with private;
> private
>   type Derived is new Parent with
>     record
>       Sub_Name: Unbounded_String;
>     end record;
> end Derived;
Oops : package and type name share the same name and you there are use
clause... the use clause is particularly evil here.

> $ gnatmake -c parent derived.ads
> gcc -c derived.ads
> derived.ads:3:23: subtype mark required in this context
> derived.ads:3:23: found "Parent" declared at parent.ads:2
The message refer to
> package Parent is

> derived.ads:5:23: subtype mark required in this context
> derived.ads:5:23: found "Parent" declared at parent.ads:2
The same as above

Either rename your packages (like Parents and Deriveds ... although
the latter is not correct English) or drop the use clause and refer to
your Parent ancestor as Parent.Parent instead.

By the way, the With clause for Ada.Strings.Unbounded is missing in
Derived.ads
From: Jean-Pierre Rosen on
Hibou57 (Yannick Duch�ne) a �crit :
> On 9 f�v, 03:16, Bryan <brobinson....(a)gmail.com> wrote:
> Oops : package and type name share the same name and you there are use
> clause... the use clause is particularly evil here.
Why? The use clause has no effect in this case!

>> $ gnatmake -c parent derived.ads
>> gcc -c derived.ads
>> derived.ads:3:23: subtype mark required in this context
>> derived.ads:3:23: found "Parent" declared at parent.ads:2
> The message refer to
>> package Parent is
>
>> derived.ads:5:23: subtype mark required in this context
>> derived.ads:5:23: found "Parent" declared at parent.ads:2
> The same as above
>
> Either rename your packages (like Parents and Deriveds ... although
> the latter is not correct English)
or use the convention of giving the class name to the package, and some
fixed name like "object" or "instance" to the type. Full rationale for
this notation is available in my paper "A naming convention for classes
in Ada 9X", downloadable from http://www.adalog.fr/publica2.htm

> or drop the use clause and refer to
> your Parent ancestor as Parent.Parent instead.
Of course, you don't need to drop the use clause to write Parent.Parent!

I don't understand why people think that as soon as you have a use
clause, you cannot use full names. If within the scope of a use clause
you don't get what you want, or if you find that in some cases full
names are more readable, by all mean, use full notation!

--
---------------------------------------------------------
J-P. Rosen (rosen(a)adalog.fr)
Visit Adalog's web site at http://www.adalog.fr
From: Hibou57 (Yannick Duchêne) on
On 9 fév, 10:11, Jean-Pierre Rosen <ro...(a)adalog.fr> wrote:
> > clause... the use clause is particularly evil here.
With package named Parent, containing a type named Parent, having a
use clause on Parent brings into a context where the name Package can
be both resolved as a package or as a type.

The use clause is clearly involved here, as one the way to get ride of
this error is to remove the use clause. The other way being to rename
either the type either the package.

May be I was wrong to say the use clause is particularly evil there :
I should have said “ the use clause is particularly vicious there
” (due to its vicious side effect in such a kind of context).

From: Hibou57 (Yannick Duchêne) on
On 9 fév, 10:11, Jean-Pierre Rosen <ro...(a)adalog.fr> wrote:
> I don't understand why people think that as soon as you have a use
> clause, you cannot use full names. If within the scope of a use clause
> you don't get what you want, or if you find that in some cases full
> names are more readable, by all mean, use full notation!
Agree with this. True that having a Use clause does not implies the
prefix notation is not available anymore.

Well, let say in this context he should not rely on the use clause to
refer to the type Parent.