comp.lang.ada
 help / color / mirror / Atom feed
* Learning tagged types
@ 2008-02-22 23:23 mhamel_98
  2008-02-23  0:04 ` Adam Beneschan
  0 siblings, 1 reply; 3+ messages in thread
From: mhamel_98 @ 2008-02-22 23:23 UTC (permalink / raw)


Hello, this is a representative bit of code I use and, experimenting
with tagged types, want to know if/how this can be cleanly moved to a
more object oriented format.  I think I want proc and def to be
abstract procedures, that requires the "object" Proc_Def itself to be
abstract, that means declaring new packages everytime I have a new
Proc_Def?  Thanks for any pointers (no pun intended),

with Text_Io;
with Ada.Containers.Doubly_Linked_Lists;

procedure Tag_Test2 is

  type Proc_Def;

  type Proc_Ptr is access procedure (Def : Proc_Def;
                                     Val : Float);
  type Term_Ptr is access procedure (Def : Proc_Def);

  type Proc_Def is
    record
      Name : String (1 .. 4);
      Proc : Proc_Ptr;
      Term : Term_Ptr;
    end record;

  package DLL is new Ada.Containers.Doubly_Linked_Lists (Proc_Def);
  Proc_List : DLL.List;

  procedure Insert_Proc (Def : Proc_Def) is
  begin
    Proc_List.Append (Def);
  end Insert_Proc;

  function Retrieve_Proc return Proc_Def is
  begin
    return Proc_List.First_Element;
  end Retrieve_Proc;

  procedure Proc1 (Def : Proc_Def;
                   Val : Float) is
  begin
    Text_Io.Put_Line (Def.Name & ": processing - " & Val'Img);
  end Proc1;

  procedure Term1 (Def : Proc_Def) is
  begin
      Text_Io.Put_Line (Def.Name & ": shutting down");
  end Term1;

  Test_Proc : Proc_Def;

begin
  Insert_Proc (("test", Proc1'access, Term1'access));
  Test_Proc := Retrieve_Proc;
  Test_Proc.Proc (Test_Proc, 5.0);
  Test_Proc.Term (Test_Proc);
end Tag_Test2;



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

* Re: Learning tagged types
  2008-02-22 23:23 Learning tagged types mhamel_98
@ 2008-02-23  0:04 ` Adam Beneschan
  2008-02-25 19:48   ` mhamel_98
  0 siblings, 1 reply; 3+ messages in thread
From: Adam Beneschan @ 2008-02-23  0:04 UTC (permalink / raw)


On Feb 22, 3:23 pm, mhamel...@yahoo.com wrote:
> Hello, this is a representative bit of code I use and, experimenting
> with tagged types, want to know if/how this can be cleanly moved to a
> more object oriented format.  I think I want proc and def to be
> abstract procedures, that requires the "object" Proc_Def itself to be
> abstract, that means declaring new packages everytime I have a new
> Proc_Def?  Thanks for any pointers (no pun intended),
>
> with Text_Io;
> with Ada.Containers.Doubly_Linked_Lists;
>
> procedure Tag_Test2 is
>
>   type Proc_Def;
>
>   type Proc_Ptr is access procedure (Def : Proc_Def;
>                                      Val : Float);
>   type Term_Ptr is access procedure (Def : Proc_Def);
>
>   type Proc_Def is
>     record
>       Name : String (1 .. 4);
>       Proc : Proc_Ptr;
>       Term : Term_Ptr;
>     end record;

I think what you want is to declare a root type instead of Proc_Def.
I don't know what you really want to call it, but you probably want to
make it an abstract type; then, instead of Proc_Ptr and Term_Ptr,
you'd declare "Proc" and "Term" or something like that to be primitive
operations of the root type.  E.g.

   type Root is abstract tagged
     record
       Name : String (1 .. 4);
     end record;

   procedure Proc (Def : Root;  Val : Float) is abstract;
   procedure Term (Def : Root) is abstract;

You do need to declare Root in a package specification, and Proc and
Term in the same specification.  (But the package could be nested
inside a procedure, if you really want it to.)

Then whenever you want to declare a particular version of this with
its own versions of Proc and Term (such as your Proc1 and Term1
below), you'd declare a type extension:

   type Some_Type is new Root with null record;

   overriding procedure Proc (Def : Some_Type;  Val : Float);
   overriding procedure Term (Def : Some_Type);

("overriding" is an Ada 2005 extension; it's not required, but is
there to help protect against accidents.  In Ada 95, just leave that
word off.)

A caveat: In Ada 95, Some_Type can't be declared inside a procedure
unless Root was declared earlier inside that same procedure.  In Ada
2005, this restriction is relaxed, but I still think you'll have to
follow it if you use it with Doubly_Linked_Lists---otherwise you could
create a list that points to a Some_Type object after Some_Type is no
longer visible.

Of course, Some_Type doesn't have to say "with null record".  If you
like, you can add additional fields---in fact, one of the purposes of
a more object-oriented style would be so that you can have additional
data for Some_Type that is just for that type and not for every type
in the class.

Now, instead of Proc_Def in the following declarations, you'd use
Root'Class since the type could be any type in the class:

>   package DLL is new Ada.Containers.Doubly_Linked_Lists (Proc_Def);
>   Proc_List : DLL.List;
>
>   procedure Insert_Proc (Def : Proc_Def) is
>   begin
>     Proc_List.Append (Def);
>   end Insert_Proc;
>
>   function Retrieve_Proc return Proc_Def is
>   begin
>     return Proc_List.First_Element;
>   end Retrieve_Proc;

The following would be the overriding bodies of Proc and Term for your
Some_Type type:

>   procedure Proc1 (Def : Proc_Def;  -- change this to Some_Type
>                    Val : Float) is
>   begin
>     Text_Io.Put_Line (Def.Name & ": processing - " & Val'Img);
>   end Proc1;
>
>   procedure Term1 (Def : Proc_Def) is  -- change this to Some_Type
>   begin
>       Text_Io.Put_Line (Def.Name & ": shutting down");
>   end Term1;
>
>   Test_Proc : Proc_Def;
>
> begin
>   Insert_Proc (("test", Proc1'access, Term1'access));

The above would become Insert_Proc (Some_Type' (Name => "test")).

>   Test_Proc := Retrieve_Proc;
>   Test_Proc.Proc (Test_Proc, 5.0);
>   Test_Proc.Term (Test_Proc);
> end Tag_Test2;

To answer your other question: no, you don't have to declare a new
package for every new type in the class.  Some programmers like doing
that, but that's a matter of style.

I haven't actually tried this.  You may have to fill in some of the
details, and I could have gotten one or two things wrong.  But
hopefully this will at least get you started.

                               -- Adam





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

* Re: Learning tagged types
  2008-02-23  0:04 ` Adam Beneschan
@ 2008-02-25 19:48   ` mhamel_98
  0 siblings, 0 replies; 3+ messages in thread
From: mhamel_98 @ 2008-02-25 19:48 UTC (permalink / raw)


> I haven't actually tried this.  You may have to fill in some of the
> details, and I could have gotten one or two things wrong.  But
> hopefully this will at least get you started.

Thank you Adam!  That helped my understanding immensely - the only
thing I had to change was to instantiate the double linked list with
an access all root'class instead of root'class itself and fix the
resulting calls.  Thanks again =)



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

end of thread, other threads:[~2008-02-25 19:48 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2008-02-22 23:23 Learning tagged types mhamel_98
2008-02-23  0:04 ` Adam Beneschan
2008-02-25 19:48   ` mhamel_98

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