comp.lang.ada
 help / color / mirror / Atom feed
From: "Dmitry A. Kazakov" <mailbox@dmitry-kazakov.de>
Subject: Re: Instantiating private types with discriminants?
Date: Thu, 11 May 2006 12:28:20 +0200
Date: 2006-05-11T12:28:20+02:00	[thread overview]
Message-ID: <13byov3p0dqhk.yglz3nh5rpb8$.dlg@40tude.net> (raw)
In-Reply-To: GzC8g.28985$Nb2.526015@news1.nokia.com

On Thu, 11 May 2006 08:27:18 GMT, rick H wrote:

> Dmitry A. Kazakov <mailbox@dmitry-kazakov.de> wrote:
>> On Wed, 10 May 2006 16:52:32 -0500, Rick H wrote:
>> 
>>> But all this has a side-effect that I haven't considered: the fact
>>> that a variable declared as a class-wide type *requires* initialization
>>> means that the compiler can determine the variable's type statically.
>> 
>> No. It only means that the type should be determinable at run-time. There
>> are may ways to do it. You can call a function with a class-wide result.
>> 
>> It might be especially interesting to take a look at S'Class'Input
>> attribute. It "dispatches" on a "bare" tag. [ Ada 2005 will offer a
>> mechanism for fully user-defined things like this. See
>> Generic_Dispatching_Constructor. ]
>> 
>>> This means that the following will raise a constraint error:
>>> declare
>>>    Var_A : General_T'Class := Get (10);  -- Type_A
>>> begin
>>>    Put (Var_A);
>>>    Ada.Text_IO.New_Line;
>>>    Var_A := Get (100.0);      -- Type_B - constraint error!
>>>    Put (Var_A);
>>> end;
>> 
>> Yes, but this is a different thing. You cannot change tag, either
>> dynamically or statically determined. Type mutators are no-no in Ada's type
>> system.
>> 
> Objects of class-wide types notwithstanding, I modified Ludovic's code
> example to change Type_A and Type_B into linked-list elements.  That
> meant no more objects of class-wide type,

You still have it the form of class-wide pointers (Linked_List_T).

[ You can't get rid of class-wide types if you what to dispatch. ]

> so I got rid of the Get
> definitions.  The following code does exactly what I wanted from this
> cut-down example: a list of either-Integer-or-Floats.  Next mystery:
> what's the use of abstract subprograms? Put (X:in Type_A) and
> Put (X:in Type_B) "feel" like just overloaded functions - why do they
> "need" an abstract parent Put (X : in General_T)?  Since General_T
> is abstract, the latter Put will never be called.  Or have I missed the
> point again!?

Puts might be overloaded in P, but it is rather a coincidence. More
important is that they override Put of General_T. This is what allows you
to dispatch to Put if you have some object of General_T'Class. Both
overloading and overriding are forms of polymorphism, so yes, in that sense
it is similar. The difference becomes obvious if you have moved
declarations of Type_A and Type_B into separate packages. Or if you have
defined a procedure to deeply put items:

procedure Put_Them_All (Item : General_T'Class) is
    Iterator : Linked_List_T := My_List;
begin
   Put (Item);                  -- Dispatches
   while Iterator /= null loop
      Put (Iterator.all);           -- Dispatches
      Ada.Text_IO.New_Line;
      Iterator := Iterator.Next;
   end loop;
end Put_Them_All;

This procedure will work with any type derived from General_T without even
knowing that any of them exist. This is so-called class-wide procedure - it
works for the class rather than for individual types of.

Note the a class-wide pointer like Linked_List_T dereferences to a
class-wide object (General_T'Class). This is why Put (X.all) dispatches. To
do this it does not need know anything else. [ Ada is a strongly typed
language. ]

A. Abstractness of a type statically ensures that no individual objects of
this type will ever exist.

B. Abstractness of a primitive subprogram statically ensures that it never
be called.

Any type with at least one abstract primitive subprogram has to be
abstract. The reverse is wrong.

You can consider declaration of:

   procedure Put (Item : in General_T) is abstract;

as an abbreviation for:

1. there is no Put defined on General_T
2. there is Put defined on General_T'Class (it dispatches)

If Put weren't abstract, then 1. would overload 2. That couldn't cause any
conflict because the types are different: General_T /= General_T'Class.

[...]
>   declare
>      Iterator : Linked_List_T := My_List;
>   begin
>      while Iterator /= null loop
>         Put (Iterator.all);
>         Ada.Text_IO.New_Line;
>         Iterator := Iterator.all.Next;

You don't need "all" here:

   Iterator := Iterator.Next;

Ada's pointers are transparent to record member/discriminant and array
element (indexing) access.

>      end loop;
>   end;

-- 
Regards,
Dmitry A. Kazakov
http://www.dmitry-kazakov.de



  reply	other threads:[~2006-05-11 10:28 UTC|newest]

Thread overview: 34+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2006-05-09 13:17 Instantiating private types with discriminants? rick H
2006-05-09 13:45 ` Georg Bauhaus
2006-05-09 14:06   ` rick H
2006-05-09 13:56 ` Ludovic Brenta
2006-05-09 14:24   ` rick H
2006-05-09 19:48     ` Ludovic Brenta
2006-05-09 14:05 ` Dmitry A. Kazakov
2006-05-09 14:48 ` rick H
2006-05-09 15:20   ` Jerry Petrey
2006-05-09 15:42     ` rick H
2006-05-09 15:53   ` Avoiding use Ada.Tags (was Re: Instantiating private types with discriminants?) Alex R. Mosteo
2006-05-09 16:01   ` Instantiating private types with discriminants? Dmitry A. Kazakov
2006-05-10  7:42     ` rick H
2006-05-10  9:09       ` Ludovic Brenta
2006-05-10 11:49         ` Georg Bauhaus
2006-05-10 13:44         ` rick H
2006-05-10 14:21           ` Ludovic Brenta
2006-05-10 15:10             ` rick H
2006-05-10 15:45               ` Ludovic Brenta
2006-05-10 14:41           ` Dmitry A. Kazakov
2006-05-10 15:34             ` rick H
2006-05-10 19:01               ` Georg Bauhaus
2006-05-10 19:05                 ` Ludovic Brenta
2006-05-10 21:52                   ` Rick H
2006-05-11  1:17                     ` Jeffrey R. Carter
2006-05-11  7:44                     ` Dmitry A. Kazakov
2006-05-11  8:27                       ` rick H
2006-05-11 10:28                         ` Dmitry A. Kazakov [this message]
2006-05-11 15:59                           ` Robert A Duff
2006-05-12  7:37                             ` Dmitry A. Kazakov
2006-05-12  9:24                               ` Georg Bauhaus
2006-05-12 12:40                                 ` Dmitry A. Kazakov
2006-05-12 18:25                                   ` Randy Brukardt
2006-05-09 19:57   ` "Use" and "=" for Tags (was: Re: Instantiating private types with discriminants?) Jeffrey R. Carter
replies disabled

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