comp.lang.ada
 help / color / mirror / Atom feed
From: Dmitry A. Kazakov <mailbox@dmitry-kazakov.de>
Subject: Re: Q: Endless loop by dispatching
Date: Mon, 14 Jul 2003 10:48:26 +0200
Date: 2003-07-14T10:48:26+02:00	[thread overview]
Message-ID: <erm4hvsg533tp2hkhsj86tftu0s8i0ot9j@4ax.com> (raw)
In-Reply-To: 3F0ED2C8.6080409@snafu.de

On Fri, 11 Jul 2003 17:07:52 +0200, Michael Erdmann
<michael.erdmann@snafu.de> wrote:

>Dmitry A. Kazakov wrote:
>
>>>Does any body know, what this loop causes?! I am not sure
>>>if this is a bug or simply i missed the point.
>> 
>> Serialize is class-wide and a view conversion does not change the
>> tag..I.e. you have a re-dispatching case. Re-dispatching is a
>> dangerous thing. [I would like it removed from Ada]
>> 
>> So Serialize re-dispatches to B.Write which again calls Serialize.
>> From design point of view, one should never call class-wide routines
>> from specific ones, this warranties that dispatch happens only once.
>> 
>> I suppose that you want sort of procedure expansion instead of
>> complete overriding, if so, then you should explicitly call parent's
>> Write, similarly as one does it for Initialize/Finalize:
>> 
>Unfortuantly this was not the complete code. The Serialize was itended
>to do a  more complex job, which i have to replicate any where i want
>to serialize an object. The original serialize code looks some what
>like this:
>
>procedure Serialize( This : in Object'Class ) is
>   ........
>    a := next(Attributes(This'Tag))
>    while a /= null loop
>        Write( this.all, a.id );
>        a := next(....);
>    end loop;
>
>end;
>
>The procedure write is a procedures which  writes out a selected 
>attribute of an object. The procedure Serialize the complete
>object.

Thus from design point of view Write should never call Serialize.

>I would have been great when i could write something
>like this in ada:
>
>procedure Serialize( This : in Object'Class ) is
>
>    Serialize( Super( This ) );
>
>    a := next(Attributes(This'Tag))
>    while a /= null loop
>        Write( this.all, a.id );
>        a := next(....);
>    end loop;
>
>end;

It is a somewhat contradictory code. Serialize is either class-wide,
or not. If it is then it should work for all Object'Class. Then it
should not call itself. If it differs for different types then it has
to be declared as a "normal" subroutine. I would split it in two:

procedure Do_Serialize (This : Object'Class; As_If : Tag) is
begin
   loop
      a := next (Attributes (As_If));
      exit when a = null;
      Write (This, a.id); 
   end loop;
end Do_Serialize;

procedure Serialize (This : in Some_Object) is
begin
   Do_Serialize (This, Parent_Object'Tag);
   Do_Serialize (This, Some_Object'Tag);
end Serialize;

Though it is still a strange thing. Why parent's attributes cannot be
extracted from an object using next? In other words, why do you want
to extend Serialize? Why the following might be insufficient:

procedure Serialize (This : Object'Class) is
begin
   for Attribute in 1..Get_Number_Of_Attributes (This) loop
      Write (This, Attribute); 
   end loop;
end Serialize;

>I think something like this does not exist in Ada!?

Yes it does not.

[Remote things]

I wished Ada's OO be modified,

1. To have stricter contracts. Your case indicates an importance of
contracts. When you write

   Object : constant Parent'Class := Create_Child;
begin
   Foo (Parent (Object)); -- I am not what you think!

you rightfully expect that the result be of Parent. But tagged types
shamelessly break this. The result is not of Parent. It is still of
Child because the conversion does not change the type tag. It is a
clear contract violation, which leads to nasty surprises when later,
in Foo, a re-dispatch happens. The source of the problem is that tag
is a part of the object, so you cannot change it. OO-speaking the
object has an identity which cannot be changed. It might be (and is) a
great problem in other OOPL, but not in Ada which has T and T'Class
different. So one might consistently state that T objects have no
identity at all, while T'Class ones have it (through tag). And note,
that nothing would be lost, because Rosen's trick would still allow
you to add identity at your own risk. Alas, it wasn't made.

If all types will become someday 'tagged', this should be changed. For
present tagged types I would either forbid misleading view conversions
to specific types or at least make them raising Constraint_Error if
the source is not exactly of the target type:

   Parent (Object)
      -- Either illegal or Constraint_Error if not Parent
   Parent'Class (Object)
      -- Legal, and no surpises expected

2. To have an ability to refer the immediate parent [and visible
ancestor] types. However, this feature should be carefully designed to
keep a way free to multiple inheritance. Something like this:

if X in S'Class then X'Super (S) is the most specific ancestor type in
S'Class. For single inheritance case, it is abbreviated to S'Super.

For tags 'Pred and 'Succ attributes should be defined to get tags
along a derivation path:

T'Pred (S) is the tag of a base type in S'Class, T'Succ (S) is the tag
of a derived type in 'not S'Class or S' (all ancestors of S including
S). Constraint_Error if the result does not exist or is ambiguous.

---
Regards,
Dmitry Kazakov
www.dmitry-kazakov.de



  parent reply	other threads:[~2003-07-14  8:48 UTC|newest]

Thread overview: 35+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2003-07-11  8:22 Q: Endless loop by dispatching Michael Erdmann
2003-07-11  9:46 ` Jean-Pierre Rosen
2003-07-11 15:19   ` Michael Erdmann
2003-07-11 10:01 ` Q: " Dmitry A. Kazakov
2003-07-11 15:07   ` Michael Erdmann
2003-07-12  1:41     ` Jeffrey Carter
2003-07-14  8:48     ` Dmitry A. Kazakov [this message]
2003-07-14 18:38       ` Randy Brukardt
2003-07-15  8:47         ` Dmitry A. Kazakov
2003-07-15 17:23           ` Randy Brukardt
2003-07-16  8:08             ` Dmitry A. Kazakov
2003-07-16 17:44               ` Robert I. Eachus
2003-07-17  1:57               ` Robert A Duff
2003-07-18  9:10                 ` Dale Stanbrough
2003-07-18 20:26                   ` Robert I. Eachus
2003-07-18 21:35                     ` tmoran
2003-07-19  0:25                       ` Robert I. Eachus
2003-07-19  2:30                         ` tmoran
2003-07-19  5:48                           ` Robert I. Eachus
2003-07-21  8:38                             ` Dmitry A. Kazakov
2003-07-21 10:08                               ` Robert I. Eachus
2003-07-21 13:21                                 ` Dmitry A. Kazakov
2003-07-21 18:51                                   ` Robert I. Eachus
2003-07-22  7:41                                     ` Dmitry A. Kazakov
2003-07-22 10:36                                       ` Lutz Donnerhacke
2003-07-22 12:11                                         ` Dmitry A. Kazakov
2003-07-22 12:18                                           ` Lutz Donnerhacke
2003-07-22 14:46                                             ` Dmitry A. Kazakov
2003-07-22 15:11                                               ` Lutz Donnerhacke
2003-07-23  8:12                                                 ` Dmitry A. Kazakov
2003-07-19 14:44                     ` Chad R. Meiners
2003-07-20 12:36                       ` Robert I. Eachus
2003-07-11 16:27 ` T. Kurt Bond
2003-07-12  8:37   ` Michael Erdmann
2003-07-15  7:11     ` Kenneth Almquist
replies disabled

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