comp.lang.ada
 help / color / mirror / Atom feed
* how to import a package
@ 2006-12-06  2:14 markww
  2006-12-06  3:06 ` Adam Beneschan
  2006-12-06 19:47 ` Jeffrey R. Carter
  0 siblings, 2 replies; 25+ messages in thread
From: markww @ 2006-12-06  2:14 UTC (permalink / raw)


Hi,

I have this snippet of code (from members here) which defines a generic
type:

    generic
    type T is private;
        package P is
    type Node;
    type Node_Ptr is access Node;
        type Node is record
            Data     : T;
            Prev_Rec : access Node; -- points to the next record or
null if none exists.
            Next_Rec : access Node; -- points to the previous record or
null if none exists.
        end record;
    end P;

Now my compiler (gnat) complains that Node, and Node_Ptr are not seen
by the rest of the application. Is this because they are scoped within
package P?

If so, how do I 'import' the package? Right now I just stuck this at
the start of my main procedure:


procedure my_project is

    generic
    type T is private;
        package P is
    type Node;
    type Node_Ptr is access Node;
        type Node is record
            Data     : T;
            Prev_Rec : access Node; -- points to the next record or
null if none exists.
            Next_Rec : access Node; -- points to the previous record or
null if none exists.
        end record;
    end P;


    type PERSON_REC;
    type PERSON_REC_POINT is access PERSON_REC;
    type PERSON_REC is
        record
            m_strName    : UNBOUNDED_STRING;
            m_strPhone   : UNBOUNDED_STRING;
            m_strAddress : UNBOUNDED_STRING;
        end record;

so I thought it would have been visible by the rest of the application.


Thanks,
Mark 
    -- etc...




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

* Re: how to import a package
  2006-12-06  2:14 how to import a package markww
@ 2006-12-06  3:06 ` Adam Beneschan
  2006-12-06  3:34   ` markww
  2006-12-06 19:47 ` Jeffrey R. Carter
  1 sibling, 1 reply; 25+ messages in thread
From: Adam Beneschan @ 2006-12-06  3:06 UTC (permalink / raw)


markww wrote:
> Hi,
>
> I have this snippet of code (from members here) which defines a generic
> type:
>
>     generic
>     type T is private;
>         package P is
>     type Node;
>     type Node_Ptr is access Node;
>         type Node is record
>             Data     : T;
>             Prev_Rec : access Node; -- points to the next record or
> null if none exists.
>             Next_Rec : access Node; -- points to the previous record or
> null if none exists.
>         end record;
>     end P;
>
> Now my compiler (gnat) complains that Node, and Node_Ptr are not seen
> by the rest of the application. Is this because they are scoped within
> package P?
>
> If so, how do I 'import' the package? Right now I just stuck this at
> the start of my main procedure:

P is a generic package so you have to instantiate it.  Something like:

   package Person_List is new P (T => Person_Rec);

Now, Node and Node_Ptr are visible within Person_List, and the "Data"
field in Person_List.Node will have type Person_Rec.

There's no such thing as a "generic type" in Ada.

                -- Adam




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

* Re: how to import a package
  2006-12-06  3:06 ` Adam Beneschan
@ 2006-12-06  3:34   ` markww
  2006-12-06  9:18     ` Simon Wright
  0 siblings, 1 reply; 25+ messages in thread
From: markww @ 2006-12-06  3:34 UTC (permalink / raw)


Hi Adam,

Thanks for your help. Now I've instantiated a list of my ppl records.
Right underneath the generic package definition I had:

    Start  : Node_Ptr;
    Last   : Node_Ptr;

but Node_Ptr is not visible. Is it no longer possible to have those two
variables declared like that?

Thanks,
Mark


Adam Beneschan wrote:
> markww wrote:
> > Hi,
> >
> > I have this snippet of code (from members here) which defines a generic
> > type:
> >
> >     generic
> >     type T is private;
> >         package P is
> >     type Node;
> >     type Node_Ptr is access Node;
> >         type Node is record
> >             Data     : T;
> >             Prev_Rec : access Node; -- points to the next record or
> > null if none exists.
> >             Next_Rec : access Node; -- points to the previous record or
> > null if none exists.
> >         end record;
> >     end P;
> >
> > Now my compiler (gnat) complains that Node, and Node_Ptr are not seen
> > by the rest of the application. Is this because they are scoped within
> > package P?
> >
> > If so, how do I 'import' the package? Right now I just stuck this at
> > the start of my main procedure:
>
> P is a generic package so you have to instantiate it.  Something like:
>
>    package Person_List is new P (T => Person_Rec);
>
> Now, Node and Node_Ptr are visible within Person_List, and the "Data"
> field in Person_List.Node will have type Person_Rec.
>
> There's no such thing as a "generic type" in Ada.
> 
>                 -- Adam




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

* Re: how to import a package
  2006-12-06  3:34   ` markww
@ 2006-12-06  9:18     ` Simon Wright
  0 siblings, 0 replies; 25+ messages in thread
From: Simon Wright @ 2006-12-06  9:18 UTC (permalink / raw)


"markww" <markww@gmail.com> writes:

(it would be easier to comment on this if you didn't top-post! I've
re-organised ...)

> Adam Beneschan wrote:
>> P is a generic package so you have to instantiate it.  Something like:
>>
>>    package Person_List is new P (T => Person_Rec);
>>
>> Now, Node and Node_Ptr are visible within Person_List, and the "Data"
>> field in Person_List.Node will have type Person_Rec.

> Thanks for your help. Now I've instantiated a list of my ppl records.
> Right underneath the generic package definition I had:
>
>     Start  : Node_Ptr;
>     Last   : Node_Ptr;
>
> but Node_Ptr is not visible. Is it no longer possible to have those two
> variables declared like that?

Either say

    Start : Person_List.Node_Ptr;

(assuming Adam's instantiation) or 'use' the instantiation:

   package Person_List is new P (T => Person_Rec);
   use Person_List;

--S



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

* Re: how to import a package
  2006-12-06  2:14 how to import a package markww
  2006-12-06  3:06 ` Adam Beneschan
@ 2006-12-06 19:47 ` Jeffrey R. Carter
  2006-12-06 23:56   ` markww
  1 sibling, 1 reply; 25+ messages in thread
From: Jeffrey R. Carter @ 2006-12-06 19:47 UTC (permalink / raw)


markww wrote:
> Hi,
> 
> I have this snippet of code (from members here) which defines a generic
> type:
> 
>     generic
>     type T is private;
>         package P is
>     type Node;
>     type Node_Ptr is access Node;
>         type Node is record
>             Data     : T;
>             Prev_Rec : access Node; -- points to the next record or
> null if none exists.
>             Next_Rec : access Node; -- points to the previous record or
> null if none exists.
>         end record;
>     end P;
> 
> Now my compiler (gnat) complains that Node, and Node_Ptr are not seen
> by the rest of the application. Is this because they are scoped within
> package P?

Package are very basic to Ada. 1st you must know how to make use of a 
package. If you don't know that, you're not ready to do anything useful 
with Ada. In general, if you have a library-level package P, you make it 
visible to another compilation unit through a context clause:

with P;
package Q is
    ...

In this case, you have a generic package, which is not a package but a 
way to create a package tailored to your needs. You can only mention a 
generic package in a context clause or instantiation. You still have to 
mention it in a context clause:

with P;
procedure My_Project is

then you have to use it to make a new package (instantiation):

package X is new P (T => Person_Rec);

Now the things declared in P are available in X. You have to use a 
qualified name to access them: X. Node. (Since you're a beginner, I'd 
recommend avoiding the use clause until you have a better idea how these 
things work.)

The above is for the most common case that P is a library-level generic 
package. In your case it appears your generic package is declared in 
your main procedure (which is not very useful), so it is not 
library-level and is directly visible; you neither need nor can use a 
context clause for P.

But all this is very basic. You should work through a tutorial or text 
and understand packages and generic packages before trying this; both 
are available at adapower.com or adaworld.com.

It would also help if you used basic Ada indentation standards:

generic
    type T is private;
package P is
    type Node;
    ...
end P;

Again, by the time you've worked through a tutorial or text you should 
have been exposed to a bunch of examples, and will hopefully have seen 
the logic behind the common indentation approach.

If you've already been through a tutorial or text, including generics, 
then there's something you didn't understand. In that case, I'm not sure 
which part you didn't understand.

-- 
Jeff Carter
"People called Romanes, they go the house?"
Monty Python's Life of Brian
79



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

* Re: how to import a package
  2006-12-06 19:47 ` Jeffrey R. Carter
@ 2006-12-06 23:56   ` markww
  2006-12-07  1:18     ` Björn Persson
                       ` (2 more replies)
  0 siblings, 3 replies; 25+ messages in thread
From: markww @ 2006-12-06 23:56 UTC (permalink / raw)


Yes I'm still confused - sorry - I'm coming from C++ / java and the ada
syntax / scoping is a bit strange to me. So I thought a package is
equivalent to a structure/class.

I thought that the following line:

    package Person_List in new P (T => PERSON_REC)

is just instantiating one instance of the package called Person_List.
So the line:

    Start : Person_List.Node_Ptr;

doesn't make sense to me since it looks like 'Start' is being defined
as pointing to Person_List.Node_Ptr, when I thought the right side of
the colon must be a data type.

In any event, I can't event get past adding the following line under
the package:

     package Person_List is new P (T => PERSON_REC);

my compiler (gnat) gives an error saying:

    operator for type "Node_Ptr" defined at line 23, nstance at line 39
is not directly visible
    use clause would make operation legal

line 39 is the line I just listed above. Line 23 is where Node_Ptr is
defined in the package. So ok, I stick the line:

    use Person_List;

underneath 'package Person_List is new P (T => PERSON_REC); ' but the
compiler still throws the same error.

Thanks,
Mark



Jeffrey R. Carter wrote:
> markww wrote:
> > Hi,
> >
> > I have this snippet of code (from members here) which defines a generic
> > type:
> >
> >     generic
> >     type T is private;
> >         package P is
> >     type Node;
> >     type Node_Ptr is access Node;
> >         type Node is record
> >             Data     : T;
> >             Prev_Rec : access Node; -- points to the next record or
> > null if none exists.
> >             Next_Rec : access Node; -- points to the previous record or
> > null if none exists.
> >         end record;
> >     end P;
> >
> > Now my compiler (gnat) complains that Node, and Node_Ptr are not seen
> > by the rest of the application. Is this because they are scoped within
> > package P?
>
> Package are very basic to Ada. 1st you must know how to make use of a
> package. If you don't know that, you're not ready to do anything useful
> with Ada. In general, if you have a library-level package P, you make it
> visible to another compilation unit through a context clause:
>
> with P;
> package Q is
>     ...
>
> In this case, you have a generic package, which is not a package but a
> way to create a package tailored to your needs. You can only mention a
> generic package in a context clause or instantiation. You still have to
> mention it in a context clause:
>
> with P;
> procedure My_Project is
>
> then you have to use it to make a new package (instantiation):
>
> package X is new P (T => Person_Rec);
>
> Now the things declared in P are available in X. You have to use a
> qualified name to access them: X. Node. (Since you're a beginner, I'd
> recommend avoiding the use clause until you have a better idea how these
> things work.)
>
> The above is for the most common case that P is a library-level generic
> package. In your case it appears your generic package is declared in
> your main procedure (which is not very useful), so it is not
> library-level and is directly visible; you neither need nor can use a
> context clause for P.
>
> But all this is very basic. You should work through a tutorial or text
> and understand packages and generic packages before trying this; both
> are available at adapower.com or adaworld.com.
>
> It would also help if you used basic Ada indentation standards:
>
> generic
>     type T is private;
> package P is
>     type Node;
>     ...
> end P;
>
> Again, by the time you've worked through a tutorial or text you should
> have been exposed to a bunch of examples, and will hopefully have seen
> the logic behind the common indentation approach.
>
> If you've already been through a tutorial or text, including generics,
> then there's something you didn't understand. In that case, I'm not sure
> which part you didn't understand.
>
> --
> Jeff Carter
> "People called Romanes, they go the house?"
> Monty Python's Life of Brian
> 79




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

* Re: how to import a package
  2006-12-06 23:56   ` markww
@ 2006-12-07  1:18     ` Björn Persson
  2006-12-07  1:26     ` Brian May
  2006-12-07  4:06     ` Jeffrey R. Carter
  2 siblings, 0 replies; 25+ messages in thread
From: Björn Persson @ 2006-12-07  1:18 UTC (permalink / raw)


markww wrote:

> Yes I'm still confused - sorry - I'm coming from C++ / java and the ada
> syntax / scoping is a bit strange to me. So I thought a package is
> equivalent to a structure/class.

No, a struct in C would be a record in Ada. A class in C++ corresponds to a
tagged record type in Ada. C++ doesn't have anything quite like a package;
I'd say the closest you get is a namespace. In Java, the classes serve as
both data types and packages. Not so in Ada. An Ada package isn't a data
type any more than a C++ namespace is.

What you have is a generic package. Generics in Ada fill the same role as
templates in C++, but they're not quite the same thing. When you
instantiate a C++ template you get a class ? a data type. When you
instantiate a generic package in Ada you get a package, which can in turn
contain data types, subprograms and other things. (Ada also has generic
subprograms, but no generic data types.)

> So the line:
> 
>     Start : Person_List.Node_Ptr;
> 
> doesn't make sense to me since it looks like 'Start' is being defined
> as pointing to Person_List.Node_Ptr, when I thought the right side of
> the colon must be a data type.

Right. Node_Ptr is a data type, and its declaration is to be found in the
package Person_List. Start is an object (a variable) of this type.

-- 
Bj�rn Persson                              PGP key A88682FD
                   omb jor ers @sv ge.
                   r o.b n.p son eri nu



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

* Re: how to import a package
  2006-12-06 23:56   ` markww
  2006-12-07  1:18     ` Björn Persson
@ 2006-12-07  1:26     ` Brian May
  2006-12-07  4:14       ` markww
  2006-12-07  4:06     ` Jeffrey R. Carter
  2 siblings, 1 reply; 25+ messages in thread
From: Brian May @ 2006-12-07  1:26 UTC (permalink / raw)


>>>>> "markww" == markww  <markww@gmail.com> writes:

    markww> I thought that the following line:

    markww>     package Person_List in new P (T => PERSON_REC)

    markww> is just instantiating one instance of the package called
    markww> Person_List.  So the line:

    markww>     Start : Person_List.Node_Ptr;

In Ada, a package is not a type (unlike in, say Java where a class is
a type and a package).

So the above defines Start to of type Node_Ptr as found in the
Person_List package.

    markww> doesn't make sense to me since it looks like 'Start' is
    markww> being defined as pointing to Person_List.Node_Ptr, when I
    markww> thought the right side of the colon must be a data type.

Correct.
-- 
Brian May <bam@snoopy.apana.org.au>



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

* Re: how to import a package
  2006-12-06 23:56   ` markww
  2006-12-07  1:18     ` Björn Persson
  2006-12-07  1:26     ` Brian May
@ 2006-12-07  4:06     ` Jeffrey R. Carter
  2 siblings, 0 replies; 25+ messages in thread
From: Jeffrey R. Carter @ 2006-12-07  4:06 UTC (permalink / raw)


markww wrote:
> Yes I'm still confused - sorry - I'm coming from C++ / java and the ada
> syntax / scoping is a bit strange to me. So I thought a package is
> equivalent to a structure/class.

A package provides modularity, encapsulation, information hiding, and 
namespace control. A C++ struct is the equivalent of an Ada record type. 
A C++ class provides encapsulation and information hiding. C++ 
namespaces provide namespace control. Nothing in C++ provides 
modularity, although header files and preprocessor textual inclusion 
provide an imitation.

> I thought that the following line:
> 
>     package Person_List in new P (T => PERSON_REC)
> 
> is just instantiating one instance of the package called Person_List.

Right. P is a generic package, and this creates an instantiation of it, 
a package named Person_List.

> So the line:
> 
>     Start : Person_List.Node_Ptr;
> 
> doesn't make sense to me since it looks like 'Start' is being defined
> as pointing to Person_List.Node_Ptr, when I thought the right side of
> the colon must be a data type.

Start is a variable object, of type Person_List.Node_Ptr. The type's 
simple name is Node_Ptr, but that's not visible. The expanded name 
(Person_List.Node_Ptr) means it's Node_Ptr in Person_List.

> In any event, I can't event get past adding the following line under
> the package:
> 
>      package Person_List is new P (T => PERSON_REC);
> 
> my compiler (gnat) gives an error saying:
> 
>     operator for type "Node_Ptr" defined at line 23, nstance at line 39
> is not directly visible
>     use clause would make operation legal

That's an odd msg; without more context I don't know what it's trying to 
tell you. This line has to come after the declaration of Person_Rec.

-- 
Jeff Carter
"People called Romanes, they go the house?"
Monty Python's Life of Brian
79



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

* Re: how to import a package
  2006-12-07  1:26     ` Brian May
@ 2006-12-07  4:14       ` markww
  2006-12-07  4:40         ` Brian May
  0 siblings, 1 reply; 25+ messages in thread
From: markww @ 2006-12-07  4:14 UTC (permalink / raw)


Ok so I moved the package into another file, compiled it separately,
and it seems to import now. Looks like:

    package Node is new GenericNode(T => PERSON_REC);
    use Node;

and now I can declare variables like:

    Start : Node.Node_Ptr;

which is very excellent. Thanks for your help with that. I thought it
would be smooth sailing now but I ran into one other minor problem
related to this which I think is just a syntax problem. I've defined a
function to count the # of nodes I have like:

    function GetRecordCount(Starting_Point : Node.Node_Ptr) return
INTEGER is
    Temp : Node.Node_Ptr;
        nCount : INTEGER := 0;
        begin
            Temp := Starting_Point;
             if Temp = null then
                 return 0;
             else
                 loop
                     nCount := nCount + 1;
                     Temp   := Temp.Next_Rec;   // PROBLEM
                     if Temp = null then
                         return nCount;
                     end if;
                 end loop;
            end if;
   end GetRecordCount;

but I get an error at line:

    Temp := Temp.Next_Rec;

    expected type "Node_Ptr" defined at genericnode.ads:9, instance at
line 29

do I need to use some special syntax to do that assignment? Next_Rec is
of type Node_Ptr so I don't see why it's causing an error.

Thanks,
Mark




Brian May wrote:
> >>>>> "markww" == markww  <markww@gmail.com> writes:
>
>     markww> I thought that the following line:
>
>     markww>     package Person_List in new P (T => PERSON_REC)
>
>     markww> is just instantiating one instance of the package called
>     markww> Person_List.  So the line:
>
>     markww>     Start : Person_List.Node_Ptr;
>
> In Ada, a package is not a type (unlike in, say Java where a class is
> a type and a package).
>
> So the above defines Start to of type Node_Ptr as found in the
> Person_List package.
>
>     markww> doesn't make sense to me since it looks like 'Start' is
>     markww> being defined as pointing to Person_List.Node_Ptr, when I
>     markww> thought the right side of the colon must be a data type.
> 
> Correct.
> -- 
> Brian May <bam@snoopy.apana.org.au>




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

* Re: how to import a package
  2006-12-07  4:14       ` markww
@ 2006-12-07  4:40         ` Brian May
  2006-12-07  9:32           ` Stuart
  0 siblings, 1 reply; 25+ messages in thread
From: Brian May @ 2006-12-07  4:40 UTC (permalink / raw)


>>>>> "markww" == markww  <markww@gmail.com> writes:

    markww> Ok so I moved the package into another file, compiled it separately,
    markww> and it seems to import now. Looks like:

    markww> package Node is new GenericNode(T => PERSON_REC);
    markww> use Node;

    markww> and now I can declare variables like:

    markww> Start : Node.Node_Ptr;

    markww> which is very excellent. Thanks for your help with that. I thought it
    markww> would be smooth sailing now but I ran into one other minor problem
    markww> related to this which I think is just a syntax problem. I've defined a
    markww> function to count the # of nodes I have like:

    markww> function GetRecordCount(Starting_Point : Node.Node_Ptr) return
    markww> INTEGER is
    markww> Temp : Node.Node_Ptr;
    markww> nCount : INTEGER := 0;
    markww> begin
    markww> Temp := Starting_Point;
    markww> if Temp = null then
    markww> return 0;
    markww> else
    markww> loop
    markww> nCount := nCount + 1;
    markww> Temp   := Temp.Next_Rec;   // PROBLEM
    markww> if Temp = null then
    markww> return nCount;
    markww> end if;
    markww> end loop;
    markww> end if;
    markww> end GetRecordCount;

    markww> but I get an error at line:

    markww> Temp := Temp.Next_Rec;

    markww> expected type "Node_Ptr" defined at genericnode.ads:9, instance at
    markww> line 29

    markww> do I need to use some special syntax to do that assignment? Next_Rec is
    markww> of type Node_Ptr so I don't see why it's causing an error.

Going back in time, you said you defined Next_Rec as:

type Node;
type Node_Ptr is access Node;
type Node is record
            Data     : T;
            Prev_Rec : access Node;
            Next_Rec : access Node;
end record;

Note that "access Node" is not the same thing as "Node_Ptr".

From memory the first is an "anonymous access type", but my memory is
a bit rusty on this topic right now (Ada 2005 feature when used in a
record?).

I think you want to replace "access Node" with "Node_Ptr".
-- 
Brian May <bam@snoopy.apana.org.au>



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

* Re: how to import a package
  2006-12-07  4:40         ` Brian May
@ 2006-12-07  9:32           ` Stuart
  2006-12-07 11:21             ` Jean-Pierre Rosen
  0 siblings, 1 reply; 25+ messages in thread
From: Stuart @ 2006-12-07  9:32 UTC (permalink / raw)


"Brian May" <bam@snoopy.apana.org.au> wrote in message 
news:sa4veko5ndy.fsf@margay.local...
>>>>>> "markww" == markww  <markww@gmail.com> writes:
> Going back in time, you said you defined Next_Rec as:
>
> type Node;
> type Node_Ptr is access Node;
> type Node is record
>            Data     : T;
>            Prev_Rec : access Node;
>            Next_Rec : access Node;
> end record;
>
> Note that "access Node" is not the same thing as "Node_Ptr".
>
> From memory the first is an "anonymous access type", but my memory is
> a bit rusty on this topic right now (Ada 2005 feature when used in a
> record?).

Ada is very particular about type matching and this can lead to some 
consequences that, at first, appear very odd.
If you look at this example:
   package P is
      pragma Elaborate_Body(P);  -- Allow a package body to exist!
   end P;

   package body P is
      type T is array(0..5) of integer;
      A, B : array(0..5) of integer;
      C, D : T;
   begin
      A := B;
      -- Not allowed because types don't match!
      C := D;
      -- Types match!
   end P;

Even though A and B appear in the same statement, they are of different 
anonymous types.  This is because
      A, B : array(0..5) of integer;
is equivalent to

      A : array(0..5) of integer;
      B : array(0..5) of integer;
and, as you may already have realized, homographs are not treated as being 
the same in Ada.

However, both C and D are of the same named type - even though the type T 
has an anonymous type as an index range.  I think it is better to avoid 
anonymous types - so the declaration of T might be better written as:
      type T_index is range 0..5;
      type T is array(T_index) of integer;

-- 
Stuart 





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

* Re: how to import a package
  2006-12-07  9:32           ` Stuart
@ 2006-12-07 11:21             ` Jean-Pierre Rosen
  2006-12-11  6:16               ` markww
  0 siblings, 1 reply; 25+ messages in thread
From: Jean-Pierre Rosen @ 2006-12-07 11:21 UTC (permalink / raw)


Stuart a �crit :
>    package body P is
>       type T is array(0..5) of integer;
>       A, B : array(0..5) of integer;
>       C, D : T;
>    begin
>       A := B;
>       -- Not allowed because types don't match!
>       C := D;
>       -- Types match!
>    end P;
> 
> [...]
> However, both C and D are of the same named type - even though the type T 
> has an anonymous type as an index range.  I think it is better to avoid 
> anonymous types - so the declaration of T might be better written as:
>       type T_index is range 0..5;
>       type T is array(T_index) of integer;
> 
Just nit-picking, the index type of T is not anonymous, it is 
Standard.Integer by default, therefore the aboved declaration is not 
equivalent.

Agreed, it is best to avoid hidden use of Standard.Integer. If you need 
Integer as the index type, better use:
type T is array (Integer range 0..5) of Integer;

Note that this remark is also applicable to loops. Rather than:
for I in 1..10 loop

write:
for I in Integer range 1..10 loop

(small plug: there is a rule in AdaControl to check the above)
-- 
---------------------------------------------------------
            J-P. Rosen (rosen@adalog.fr)
Visit Adalog's web site at http://www.adalog.fr



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

* Re: how to import a package
  2006-12-07 11:21             ` Jean-Pierre Rosen
@ 2006-12-11  6:16               ` markww
  2006-12-11  6:50                 ` markww
  2006-12-11  7:00                 ` Simon Wright
  0 siblings, 2 replies; 25+ messages in thread
From: markww @ 2006-12-11  6:16 UTC (permalink / raw)


Ok I still don't understand why this assignment is illegal though -
here's a test I have:

    generic
        type T is private;
    package GenericNode is
        type Node;
        type Node_Ptr is access Node;
        type Node is record
            Data     : T;           -- the generic data we want to
store in a node.
            Prev_Rec : access Node_Ptr; -- points to the next record or
null if none exists.
            Next_Rec : access Node_Ptr; -- points to the previous
record or null if none exists.
        end record;
    end GenericNode;

now later...

    package gNode is new GenericNode(T => PERSON_REC);
    use gNode;

    function Test(whatever : INTEGER) return INTEGER is
    Temp : gNode.Node_Ptr;
    begin
        Temp := Temp.Next_Rec; -- no!!!!!!!!!!!!!!!!
        return 0;
    end Test;

Why is the Temp assignment not possible? The compiler says: expected
type Node_Ptr defined in genericnode.ads. But I have defined it as type
Node_Ptr.

Thanks,
Mark



Jean-Pierre Rosen wrote:
> Stuart a écrit :
> >    package body P is
> >       type T is array(0..5) of integer;
> >       A, B : array(0..5) of integer;
> >       C, D : T;
> >    begin
> >       A := B;
> >       -- Not allowed because types don't match!
> >       C := D;
> >       -- Types match!
> >    end P;
> >
> > [...]
> > However, both C and D are of the same named type - even though the type T
> > has an anonymous type as an index range.  I think it is better to avoid
> > anonymous types - so the declaration of T might be better written as:
> >       type T_index is range 0..5;
> >       type T is array(T_index) of integer;
> >
> Just nit-picking, the index type of T is not anonymous, it is
> Standard.Integer by default, therefore the aboved declaration is not
> equivalent.
>
> Agreed, it is best to avoid hidden use of Standard.Integer. If you need
> Integer as the index type, better use:
> type T is array (Integer range 0..5) of Integer;
>
> Note that this remark is also applicable to loops. Rather than:
> for I in 1..10 loop
>
> write:
> for I in Integer range 1..10 loop
>
> (small plug: there is a rule in AdaControl to check the above)
> --
> ---------------------------------------------------------
>             J-P. Rosen (rosen@adalog.fr)
> Visit Adalog's web site at http://www.adalog.fr




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

* Re: how to import a package
  2006-12-11  6:16               ` markww
@ 2006-12-11  6:50                 ` markww
  2006-12-11  9:40                   ` Georg Bauhaus
  2006-12-11  7:00                 ` Simon Wright
  1 sibling, 1 reply; 25+ messages in thread
From: markww @ 2006-12-11  6:50 UTC (permalink / raw)


Ok I removed the 'access' keyword for the Next_Rec/Prev_Rec definitions
and that seems to have cleared that issue up.

I hope this is the last problem I run into , the rest of the app is
compiling ok. I used to have a procedure that would add a person_rec to
my linked list. I'm trying to update it so it takes a generic type and
gets added to the linked list instead. So I made a test function like:

     procedure Add_Record(GenericData : gNode.T) is
     Temp : gNode.Node_Ptr;
     begin
         Temp := new gNode.Node;
         Temp.Data := GenericData;
     end Add_Record;

now the compiler is saying that my generic type T is not visible to the
rest of the application. It's in the imported package though and all
the rest of the parts are visible. How do I make it visible?

Also, is this procedure definition correct? In C++ it's easy to do this
after defining a type it would be just:

    bool Add_Record (T t);
    template<typename T>
    bool CLinkedList<T>::Add_Record(T t)
    {
        // ...
    }

I'm guessing it must be similar.

Thanks,
Mark




markww wrote:
> Ok I still don't understand why this assignment is illegal though -
> here's a test I have:
>
>     generic
>         type T is private;
>     package GenericNode is
>         type Node;
>         type Node_Ptr is access Node;
>         type Node is record
>             Data     : T;           -- the generic data we want to
> store in a node.
>             Prev_Rec : access Node_Ptr; -- points to the next record or
> null if none exists.
>             Next_Rec : access Node_Ptr; -- points to the previous
> record or null if none exists.
>         end record;
>     end GenericNode;
>
> now later...
>
>     package gNode is new GenericNode(T => PERSON_REC);
>     use gNode;
>
>     function Test(whatever : INTEGER) return INTEGER is
>     Temp : gNode.Node_Ptr;
>     begin
>         Temp := Temp.Next_Rec; -- no!!!!!!!!!!!!!!!!
>         return 0;
>     end Test;
>
> Why is the Temp assignment not possible? The compiler says: expected
> type Node_Ptr defined in genericnode.ads. But I have defined it as type
> Node_Ptr.
>
> Thanks,
> Mark
>
>
>
> Jean-Pierre Rosen wrote:
> > Stuart a écrit :
> > >    package body P is
> > >       type T is array(0..5) of integer;
> > >       A, B : array(0..5) of integer;
> > >       C, D : T;
> > >    begin
> > >       A := B;
> > >       -- Not allowed because types don't match!
> > >       C := D;
> > >       -- Types match!
> > >    end P;
> > >
> > > [...]
> > > However, both C and D are of the same named type - even though the type T
> > > has an anonymous type as an index range.  I think it is better to avoid
> > > anonymous types - so the declaration of T might be better written as:
> > >       type T_index is range 0..5;
> > >       type T is array(T_index) of integer;
> > >
> > Just nit-picking, the index type of T is not anonymous, it is
> > Standard.Integer by default, therefore the aboved declaration is not
> > equivalent.
> >
> > Agreed, it is best to avoid hidden use of Standard.Integer. If you need
> > Integer as the index type, better use:
> > type T is array (Integer range 0..5) of Integer;
> >
> > Note that this remark is also applicable to loops. Rather than:
> > for I in 1..10 loop
> >
> > write:
> > for I in Integer range 1..10 loop
> >
> > (small plug: there is a rule in AdaControl to check the above)
> > --
> > ---------------------------------------------------------
> >             J-P. Rosen (rosen@adalog.fr)
> > Visit Adalog's web site at http://www.adalog.fr




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

* Re: how to import a package
  2006-12-11  6:16               ` markww
  2006-12-11  6:50                 ` markww
@ 2006-12-11  7:00                 ` Simon Wright
  1 sibling, 0 replies; 25+ messages in thread
From: Simon Wright @ 2006-12-11  7:00 UTC (permalink / raw)


"markww" <markww@gmail.com> writes:

> Ok I still don't understand why this assignment is illegal though -
> here's a test I have:
>
>     generic
>         type T is private;
>     package GenericNode is
>         type Node;
>         type Node_Ptr is access Node;
>         type Node is record
>             Data     : T;           -- the generic data we want to
> store in a node.
>             Prev_Rec : access Node_Ptr; -- points to the next record or
> null if none exists.
>             Next_Rec : access Node_Ptr; -- points to the previous
> record or null if none exists.
>         end record;
>     end GenericNode;
>
> now later...
>
>     package gNode is new GenericNode(T => PERSON_REC);
>     use gNode;
>
>     function Test(whatever : INTEGER) return INTEGER is
>     Temp : gNode.Node_Ptr;
>     begin
>         Temp := Temp.Next_Rec; -- no!!!!!!!!!!!!!!!!
>         return 0;
>     end Test;
>
> Why is the Temp assignment not possible? The compiler says: expected
> type Node_Ptr defined in genericnode.ads. But I have defined it as type
> Node_Ptr.

You've declared Next_Rec as *access* Note_Ptr. I think you meant to
declare it as just Node_Ptr.

   struct node {
      T data;
      node** prev_rec;   /* should be just node* ? */
      node** next_rec;
   };

Also, look at the way you've commented on Prev_Rec and Next_Rec. Aside
from the comments being the wrong way round, you say 'points to the
... record'. As written, it points to *a pointer to* the .. record.



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

* Re: how to import a package
  2006-12-11  6:50                 ` markww
@ 2006-12-11  9:40                   ` Georg Bauhaus
  2006-12-11 14:19                     ` markww
  0 siblings, 1 reply; 25+ messages in thread
From: Georg Bauhaus @ 2006-12-11  9:40 UTC (permalink / raw)


On Sun, 2006-12-10 at 22:50 -0800, markww wrote:
>  So I made a test function like:
> 
>      procedure Add_Record(GenericData : gNode.T) is
>      Temp : gNode.Node_Ptr;
>      begin
>          Temp := new gNode.Node;
>          Temp.Data := GenericData;
>      end Add_Record;
> 
> now the compiler is saying that my generic type T is not visible to the
> rest of the application. 

The type T is in the formal part of the package, not in the package
proper. So either you are explicit about T (you have made an
instance of the package using Some_Type for T, so you can use
Some_Type instead of gNode.T there, too) or you make your generic
package have a type Gen_T by using "subtype Gen_T is T" or similar.


> Also, is this procedure definition correct? In C++ it's easy to do this
> after defining a type it would be just:
> 
>     bool Add_Record (T t);
>     template<typename T>
>     bool CLinkedList<T>::Add_Record(T t)
>     {
>         // ...
>     }

But here, you have one specific T and one generic T.





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

* Re: how to import a package
  2006-12-11  9:40                   ` Georg Bauhaus
@ 2006-12-11 14:19                     ` markww
  2006-12-11 15:03                       ` Dmitry A. Kazakov
                                         ` (2 more replies)
  0 siblings, 3 replies; 25+ messages in thread
From: markww @ 2006-12-11 14:19 UTC (permalink / raw)


Ok I just broke down and wrote the test function to take a specific
PERSON_REC type to add into a new node. The program compiles and runs
as expected, but I just lost my generics support by doing this, I
think:

    procedure Add_Record(GenericData : PERSON_REC) is
    Temp : gNode.Node_Ptr;
    begin

        Temp := new gNode.Node;
        Temp.Data := GenericData;
    end Add_Record;

So yes now it runs ok and I can print the contents of the linked list
and see that a person record was added into the Data member.

But now I can't use this Add_Record function to store some other type
of user defined data, it will only work with PERSON_RECs.

I'm sorry, I still don't understand how to just pass a generic through
as a parameter!

Thanks,
Mark



Georg Bauhaus wrote:
> On Sun, 2006-12-10 at 22:50 -0800, markww wrote:
> >  So I made a test function like:
> >
> >      procedure Add_Record(GenericData : gNode.T) is
> >      Temp : gNode.Node_Ptr;
> >      begin
> >          Temp := new gNode.Node;
> >          Temp.Data := GenericData;
> >      end Add_Record;
> >
> > now the compiler is saying that my generic type T is not visible to the
> > rest of the application.
>
> The type T is in the formal part of the package, not in the package
> proper. So either you are explicit about T (you have made an
> instance of the package using Some_Type for T, so you can use
> Some_Type instead of gNode.T there, too) or you make your generic
> package have a type Gen_T by using "subtype Gen_T is T" or similar.
>
>
> > Also, is this procedure definition correct? In C++ it's easy to do this
> > after defining a type it would be just:
> >
> >     bool Add_Record (T t);
> >     template<typename T>
> >     bool CLinkedList<T>::Add_Record(T t)
> >     {
> >         // ...
> >     }
> 
> But here, you have one specific T and one generic T.




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

* Re: how to import a package
  2006-12-11 14:19                     ` markww
@ 2006-12-11 15:03                       ` Dmitry A. Kazakov
  2006-12-11 16:22                       ` Adam Beneschan
  2006-12-11 20:28                       ` Jeffrey R. Carter
  2 siblings, 0 replies; 25+ messages in thread
From: Dmitry A. Kazakov @ 2006-12-11 15:03 UTC (permalink / raw)


On 11 Dec 2006 06:19:37 -0800, markww wrote:

> I'm sorry, I still don't understand how to just pass a generic through
> as a parameter!

No way. It is incorrect in either C++ or Ada. A generic is never a [normal]
parameter. It can only be a *generic* parameter of another generic thing.

Answering less formally, what you want to achieve is probably this:

generic
   type T is private;
package Generic_List is
   type Node;
   type Node_Ptr is access Node;
   type Node is limited record -- We don't copy nodes
      Data : T;                -- The data in the node
      Prev : Node_Ptr;         -- Previous node, else null
      Next : Node_Ptr;         -- Next node, else null
   end record;
   -- Operations defined on the nodes follow:
   --
   -- Add a new node to the list after the node indicated by
   -- the parameter After.
   --
   procedure Add (After : Node_Ptr; Data : T);
end Generic_List;
----------------------------------------------
package body Generic_List is
   procedure Add (After : Node_Ptr; Data : T) is
      New_Node : Node_Ptr := new Node;
   begin
      New_Node.Data := Data;
      New_Node.Prev := After;
      New_Node.Next := After.Next;
      if After.Next /= null then
         After.Next.Prev := New_Node;
      end if;
      After.Next := New_Node;
   end Add;
end Generic_List;
-------------------------------------------

1. T is a generic formal parameter of the package Generic_List.

2. Data is normal parameter of a procedure Add.

3. The procedure Add is not generic

4. When Generic_List is instantiated this instance will be a normal package
with a normal procedure Add in it.

5. This Add will be defined on the actual type specified for T during the
instantiation.

For example:

   package List_Of_Integers is new Generic_List (T=>Integer);
   
-- 
Regards,
Dmitry A. Kazakov
http://www.dmitry-kazakov.de



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

* Re: how to import a package
  2006-12-11 14:19                     ` markww
  2006-12-11 15:03                       ` Dmitry A. Kazakov
@ 2006-12-11 16:22                       ` Adam Beneschan
  2006-12-11 20:28                       ` Jeffrey R. Carter
  2 siblings, 0 replies; 25+ messages in thread
From: Adam Beneschan @ 2006-12-11 16:22 UTC (permalink / raw)


markww wrote:
> Ok I just broke down and wrote the test function to take a specific
> PERSON_REC type to add into a new node. The program compiles and runs
> as expected, but I just lost my generics support by doing this, I
> think:
>
>     procedure Add_Record(GenericData : PERSON_REC) is
>     Temp : gNode.Node_Ptr;
>     begin
>
>         Temp := new gNode.Node;
>         Temp.Data := GenericData;
>     end Add_Record;

> So yes now it runs ok and I can print the contents of the linked list
> and see that a person record was added into the Data member.
>
> But now I can't use this Add_Record function to store some other type
> of user defined data, it will only work with PERSON_RECs.
>
> I'm sorry, I still don't understand how to just pass a generic through
> as a parameter!

If I understand what you're trying to do, then I think you want to put
Add_Record inside the generic.  You can add this to the GenericNode
package:

    procedure Add_Record (GenericData: T);

and then set up a package body for GenericNode that contains the body
of Add_Record.  The effect is that when GenericNode is instantiated
(package <whatever> is new GenericNode...) with type PERSON_REC or
ANOTHER_REC or whatever, you will also get a new Add_Record, inside
gNode, to add records of that type.

You'll probably have to do something additional.  The way you've
written Add_Record above, it assigns Temp to be a pointer to a new
node, but then Temp isn't stored anywhere else, so that the new node
you've just created is abandoned and no one can ever access it again.
How you solve this depends on your particular design, but you may need
to turn Add_Record into a function that returns a Node_Ptr, or add an
OUT parameter whose type is Node_Ptr.

Hope this helps,

                     -- Adam




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

* Re: how to import a package
  2006-12-11 14:19                     ` markww
  2006-12-11 15:03                       ` Dmitry A. Kazakov
  2006-12-11 16:22                       ` Adam Beneschan
@ 2006-12-11 20:28                       ` Jeffrey R. Carter
  2006-12-12  3:19                         ` markww
  2 siblings, 1 reply; 25+ messages in thread
From: Jeffrey R. Carter @ 2006-12-11 20:28 UTC (permalink / raw)


markww wrote:
> 
>     procedure Add_Record(GenericData : PERSON_REC) is
>     Temp : gNode.Node_Ptr;
>     begin
> 
>         Temp := new gNode.Node;
>         Temp.Data := GenericData;
>     end Add_Record;

This leaks memory.

Others have discussed the solution to your specific problem, but I think 
what you're missing is the general mind-set that a type definition and 
the operations on that type should be encapsulated in a package. So far, 
you only have 1 operation (Add_Record), but in a generally useful 
linked-list package you'd probably have a lot more. Those operations 
should be in the package; then, whenever you instantiate the package, 
you get the operations.

This concept, encapsulation of data and their operations (usually with 
hiding of the data's structure), is called "object orientedness". In 
many languages, this design concept is mixed up with the implementation 
concept of programming by extension (incorrectly called OOP); for 
example, in C++, you get both from the "class" construct. In Ada, the 2 
are separate.

At this point, you might find it instructive to look at some existing 
linked-list packages, such as the one in the Ada-0X container library, 
or the ones in the PragmAda Reusable Components

http://pragmada.home.mchsi.com/

or many of the component libraries you can find at adapower.com or 
adaworld.com.

-- 
Jeff Carter
"Blessed is just about anyone with a vested interest in the status quo."
Monty Python's Life of Brian
73



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

* Re: how to import a package
  2006-12-11 20:28                       ` Jeffrey R. Carter
@ 2006-12-12  3:19                         ` markww
  2006-12-12  3:31                           ` Jeffrey R. Carter
                                             ` (2 more replies)
  0 siblings, 3 replies; 25+ messages in thread
From: markww @ 2006-12-12  3:19 UTC (permalink / raw)


Thanks all I think I got it now. Dmitry A. Kazakov, Adam Beneschan,
your posts really showed me how to set it up. Now I have all the list
functions as part of that package and it's working as expected for a
generic list.

I'm wondering still if it's possible to have a data member in the
package definition that serve as my start and end nodes. In C++ I'd do
something like:

    struct List {

        AddNode(...);
        DeleteNode(...);
        ...

        Node *pStart, *pEnd; // keeps track of start and end nodes for
a single list instance.
    }

am I allowed to do the same in my package definition? Then things would
be a lot neater. Right now I have the start and end pointers as
variables external to the package, so everytime I call AddNode() etc I
have to pass them through which is pretty sloppy. It looks like:

    generic
        type T is private;
    package Generic_List is
        type Node;
        type Node_Ptr is access Node;
        type Node is limited record -- We don't copy nodes
            Data : T;                -- The data in the node
            Prev : Node_Ptr;         -- Previous node, else null
            Next : Node_Ptr;         -- Next node, else null
         end record;

       procedure Add(Start : in out Node_Ptr; Last : in out Node_Ptr;
Data : T);
       procedure Delete(Start : in out Node_Ptr; Last : in out
Node_Ptr; nIndex : INTEGER);
       function GetNodeCount (Start : Node_Ptr) return INTEGER;
       function GetNode(Start : Node_Ptr; nIndex : INTEGER) return
Node_Ptr;
       function GetNodePosition(Start : Node_Ptr; MatchData : T) return
INTEGER;

      -- Something like:
      m_Start : Node_Ptr;
      m_Last : Node_Ptr;

   end Generic_List;

then externally I'd hope to use it like:

    GenericList.Add(T);

instead of what I'm doing now:

    GenericList.Add(Start, Last, T);

Thanks,
Mark

Jeffrey R. Carter wrote:
> markww wrote:
> >
> >     procedure Add_Record(GenericData : PERSON_REC) is
> >     Temp : gNode.Node_Ptr;
> >     begin
> >
> >         Temp := new gNode.Node;
> >         Temp.Data := GenericData;
> >     end Add_Record;
>
> This leaks memory.
>
> Others have discussed the solution to your specific problem, but I think
> what you're missing is the general mind-set that a type definition and
> the operations on that type should be encapsulated in a package. So far,
> you only have 1 operation (Add_Record), but in a generally useful
> linked-list package you'd probably have a lot more. Those operations
> should be in the package; then, whenever you instantiate the package,
> you get the operations.
>
> This concept, encapsulation of data and their operations (usually with
> hiding of the data's structure), is called "object orientedness". In
> many languages, this design concept is mixed up with the implementation
> concept of programming by extension (incorrectly called OOP); for
> example, in C++, you get both from the "class" construct. In Ada, the 2
> are separate.
>
> At this point, you might find it instructive to look at some existing
> linked-list packages, such as the one in the Ada-0X container library,
> or the ones in the PragmAda Reusable Components
>
> http://pragmada.home.mchsi.com/
>
> or many of the component libraries you can find at adapower.com or
> adaworld.com.
>
> --
> Jeff Carter
> "Blessed is just about anyone with a vested interest in the status quo."
> Monty Python's Life of Brian
> 73




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

* Re: how to import a package
  2006-12-12  3:19                         ` markww
@ 2006-12-12  3:31                           ` Jeffrey R. Carter
  2006-12-12  9:03                           ` Stuart
  2006-12-12 10:56                           ` Georg Bauhaus
  2 siblings, 0 replies; 25+ messages in thread
From: Jeffrey R. Carter @ 2006-12-12  3:31 UTC (permalink / raw)


markww wrote:
> 
>     generic
>         type T is private;
>     package Generic_List is
>       ...
>       -- Something like:
>       m_Start : Node_Ptr;
>       m_Last : Node_Ptr;
> 
>    end Generic_List;


You can do that, but then your package can only be a single list. If 
that's what you want, you should consider moving the type and data 
declarations to the body, and only having the operations in the spec. 
Perhaps what you really want is something like

type List is record
    First : Node_Ptr;
    Last  : Node_Ptr;
end record;

procedure Add (To : in out List; Item : in T);

-- 
Jeff Carter
"Blessed is just about anyone with a vested interest in the status quo."
Monty Python's Life of Brian
73



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

* Re: how to import a package
  2006-12-12  3:19                         ` markww
  2006-12-12  3:31                           ` Jeffrey R. Carter
@ 2006-12-12  9:03                           ` Stuart
  2006-12-12 10:56                           ` Georg Bauhaus
  2 siblings, 0 replies; 25+ messages in thread
From: Stuart @ 2006-12-12  9:03 UTC (permalink / raw)


"markww" <markww@gmail.com> wrote in message 
news:1165893584.829025.235440@l12g2000cwl.googlegroups.com...
> I'm wondering still if it's possible to have a data member in the
> package definition that serve as my start and end nodes. In C++ I'd do
> something like:

<snip C>

> am I allowed to do the same in my package definition? Then things would
> be a lot neater.

As Jeff Carter explained - yes you can.  The approach you currently have is 
often referred to as an Abstract Data Type (ADT), whereas what you are 
considering is an Abstract State Machine (ASM).  The topic is worth 
researching.  It is a very important program design consideration as to 
whether to make something an ADT or an ASM as it controls the location of 
state and the nature of the interface.  This is a lesson that is emphasized 
in the design of SPARK (see www.sparkada.com)  programs.

Given an ADT it is quite straightforward to create an ASM; you simply create 
a package that contains the state variable and replicates each of the ADT 
operations, omitting the Object parameter from their own parameter list and 
using the state variable when calling the ADT operation to provide the 
functionality.

   package ADT is
       type T is private;
       procedure Add(Item : in       integer;
                               To    : in out T);
       function Initialize(Initial : in integer) return T;
  private
     type T is integer; -- Just a demo!
  end ADT;

   with ADT;
   package ASM is
      procedure Add(Item : in integer);
   private
      State : ADT.T := ADT.Initialize(0);
   end ASM;

   package body ASM is
      procedure Add(Item : in integer) is
      begin
         ADT.Add(Item => Item,
                          To   => State);
     end Add;
   end ASM;

> Right now I have the start and end pointers as variables external to
> the package, so everytime I call AddNode() etc I have to pass
> them through which is pretty sloppy. It looks like:

Why do you have them as separate variables?  You could create a type (call 
it, say, List) that has both these components.  Having 'cracked' generics 
you might want to go back and think very carefully about what the 'visible' 
parts of your ADT/ASM are, and what are 'private' details.  Generally the 
more you make private the less chance there is of things getting messed up, 
and the easier it is to make changes to the underlying type to 
develop/extend/improve your design.

Jeff's suggestion of looking at the design of  packages like Containers is a 
good one.

Regards
-- 
Stuart





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

* Re: how to import a package
  2006-12-12  3:19                         ` markww
  2006-12-12  3:31                           ` Jeffrey R. Carter
  2006-12-12  9:03                           ` Stuart
@ 2006-12-12 10:56                           ` Georg Bauhaus
  2 siblings, 0 replies; 25+ messages in thread
From: Georg Bauhaus @ 2006-12-12 10:56 UTC (permalink / raw)


On Mon, 2006-12-11 at 19:19 -0800, markww wrote:


> I'm wondering still if it's possible to have a data member in the
> package definition that serve as my start and end nodes.

As Jeffrey and Stuart have explained, you are still led astray
by a misconception: A C++ struct/class here corresponds to an Ada
type, not to an Ada package. Although you need a package to
associate the "methods" with the tagged type, all data members
must become the record components in the type definition.

C++: From a struct or class, you create objects.
Ada: From a type, you create objects.

C++: Operations of a type are declared within the struct/class
Ada: Operations of a type are declared after the type within
     a surrounding package.

Compare the following definitions:

namespace Geo
{
  struct Any
  {
    int x, y;
    virtual void move(int a, int b) = 0;
  };

  struct Point : public Any
  {
    virtual void move(int a, int b);
  };

  struct Circle : public Any
  {
    int r;
    virtual void move(int a, int b);
  };
}


package Geo is

   type Any is abstract tagged record
      x, y: Integer;
      -- data members of any geometric object
   end record;

   procedure move(thing: in out Any; a, b: Integer) is abstract;
   -- abstract method of Any



   type Point is new Any with record
      null;
         -- no additional data members
   end record;

   --overriding
   procedure move(thing: in out Point; a, b: Integer);



   type Circle is new Any with record
      r: Integer;
      -- Circle objects with radius
   end record;

   --overriding
   procedure move(thing: in out Circle; a, b: Integer);

end Geo;

HTH,
-- Georg





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

end of thread, other threads:[~2006-12-12 10:56 UTC | newest]

Thread overview: 25+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2006-12-06  2:14 how to import a package markww
2006-12-06  3:06 ` Adam Beneschan
2006-12-06  3:34   ` markww
2006-12-06  9:18     ` Simon Wright
2006-12-06 19:47 ` Jeffrey R. Carter
2006-12-06 23:56   ` markww
2006-12-07  1:18     ` Björn Persson
2006-12-07  1:26     ` Brian May
2006-12-07  4:14       ` markww
2006-12-07  4:40         ` Brian May
2006-12-07  9:32           ` Stuart
2006-12-07 11:21             ` Jean-Pierre Rosen
2006-12-11  6:16               ` markww
2006-12-11  6:50                 ` markww
2006-12-11  9:40                   ` Georg Bauhaus
2006-12-11 14:19                     ` markww
2006-12-11 15:03                       ` Dmitry A. Kazakov
2006-12-11 16:22                       ` Adam Beneschan
2006-12-11 20:28                       ` Jeffrey R. Carter
2006-12-12  3:19                         ` markww
2006-12-12  3:31                           ` Jeffrey R. Carter
2006-12-12  9:03                           ` Stuart
2006-12-12 10:56                           ` Georg Bauhaus
2006-12-11  7:00                 ` Simon Wright
2006-12-07  4:06     ` Jeffrey R. Carter

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