comp.lang.ada
 help / color / mirror / Atom feed
From: "Matthew Heaney" <mheaney@on2.com>
Subject: Re: Merits of re-dispatching [LONG]
Date: Fri, 8 Feb 2002 18:51:00 -0500
Date: 2002-02-08T18:51:00-05:00	[thread overview]
Message-ID: <u68q8fc9t4qt1c@corp.supernews.com> (raw)
In-Reply-To: 3c6392e8.2400843@News.CIS.DFN.DE


"Dmitry A. Kazakov" <dmitry@elros.cbb-automation.de> wrote in message
news:3c6392e8.2400843@News.CIS.DFN.DE...
> First C++ does not make any difference between class wide and specific
> objects. The same type B is a class wide in B::f () and specific in
> B::~B (). So the difference in how B::f and B::~B are dealing with
> calls to g(). This is IMO bad.

It's bad to the extent that it falsifies the programmer's mental model of
how he thinks it should work.  It violates the "principle of least
astonishment."

> Second. The behaviour of B::~B is safe. One should never expect
> dispatching in a specific subroutine like destructor. My point is that
> the language should prohibit dispatching from specific subroutines.
> Therefore in my opinion the behaviour of B::f is unsafe. It is
> declared as virtual (dispatching) which means that inside B::f the
> type is already *known*. Thus there is no need in [re-]dispatching. A
> call to g() can be statically resolved.

Well, the programmer can turn off the dispatching:

void B::f()
{
   B::g();  //no dispatching
}

Here C++ and Ada95 diverge wrt syntactic overhead: in Ada95 you pay to turn
dispatching on, and in C++ you pay to turn dispatching off.

 > The reason why C++ dispatches in B::f (), is that otherwise it would
> impossible to have class wide subroutines [see the point 1]. In
> contrary to this Ada 95 does have class wide routines, so my question,
> why [explicit] re-dispatching is supported in Ada 95?

Because you may want to let a derived type override the algorithm in the
parent type.

A class-wide operation typically declares an overall algorithm, and
dispatching is used to provide the details:

package P is
   type T is tagged limited null record;
   procedure Op1 (O : T);
   procedure Op2 (O : T);
   procedure Op (O : T'Class);
end P;

package body P is
   procedure Op (O : T'Class) is  --static
   begin
      if <something> then
         Op1 (O);  --dynamic
     else
         Op2 (O);  --dynamic
     end if;
   end Op;
...
end P;

This is fine, but if you want to change the algorithm used by class-wide
operation Op, you can't.

If you want to allow a derived type to replace the whole algorithm (not just
the parts done by Op1 and Op2), then you have to make the operation
primitive for the type, and then turn on the dispatching:

package body P is
   procedure Op (O : T) is
   begin
      if <something> then
         Op1 (T'Class (O));
      else
         Op2 (T'Class (O));
      end if;
   end Op;
...
end P;

Now a derived type (say, P.C.NT) can override Op.

In general, an operation --primitive or class-wide-- should document which
dispatching operations it calls, so that a derived type knows what is
expected of it.

This was the problem with your original example: you seemed to argue that it
was some kind of language flaw in that you could call a dispatching
operation in the Finalize operation.  But this isn't bad because of any flaw
in the language, this is bad because it's a dumb thing to do.

The idiom for implementing a primitive Finalize operation is to finalize the
specific type, and then call the Finalize operation of its parent.  In
particular, this means you shouldn't call any dispatching operations.  In
practice this isn't an issue, because operations are statically bound by
default.

If a Finalize operation does call dispatching operations, then of course
this is a programmer error, no different from any other kind of programmer
error.






  parent reply	other threads:[~2002-02-08 23:51 UTC|newest]

Thread overview: 36+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2002-02-07 10:26 Merits of re-dispatching [LONG] Dmitry A. Kazakov
2002-02-07 15:03 ` Hyman Rosen
2002-02-08  1:29   ` Matthew Heaney
2002-02-08  9:16     ` Dmitry A. Kazakov
2002-02-08 18:30       ` Hyman Rosen
2002-02-09  0:10         ` Matthew Heaney
2002-02-12  8:32         ` Dmitry A. Kazakov
2002-02-12 21:37           ` Hyman Rosen
2002-02-13  9:29             ` Dmitry A. Kazakov
2002-02-13 14:32               ` Hyman Rosen
2002-02-13 19:58           ` Dave Harris
2002-02-14 15:06             ` Dmitry A. Kazakov
2002-02-16 12:10               ` Dave Harris
2002-02-18  8:57                 ` Dmitry A. Kazakov
2002-02-18 19:47                   ` Merits of re-dispatching Dave Harris
2002-02-19  9:20                     ` Dmitry A. Kazakov
2002-02-21  5:49                       ` Hyman Rosen
2002-02-21  9:04                         ` Dmitry A. Kazakov
2002-02-21 18:17                           ` Hyman Rosen
2002-02-22  9:21                             ` Dmitry A. Kazakov
2002-02-22 16:59                               ` Hyman Rosen
2002-02-25  8:51                                 ` Dmitry A. Kazakov
2002-02-08 23:51       ` Matthew Heaney [this message]
2002-02-12  9:02         ` Merits of re-dispatching [LONG] Dmitry A. Kazakov
2002-02-07 23:40 ` Nick Roberts
2002-02-08  8:56   ` Dmitry A. Kazakov
2002-02-08  1:06 ` Matthew Heaney
2002-02-08  9:48   ` Dmitry A. Kazakov
2002-02-09  0:16     ` Matthew Heaney
2002-02-08 18:10   ` Hyman Rosen
2002-02-09  0:41     ` Matthew Heaney
2002-02-08 18:33 ` Nick Roberts
2002-02-09  4:07   ` Nick Roberts
2002-02-12 10:13   ` Dmitry A. Kazakov
2002-02-14 20:57 ` Tucker Taft
2002-02-15 15:43   ` Dmitry A. Kazakov
replies disabled

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