From: shang@corp.mot.com (David (Lujun) Shang)
Subject: Re: run-time type checking (was: Re: Covariant Types in Derived Classes)
Reply-To: shang@corp.mot.com
Organization: Motorola, Inc., Software Research and Development, Rolling Meadows, IL. 60008
Date: Fri, 24 Jul 92 23:46:28 GMT

> >(John MAX Skaller) writes: 
>We design our systems properly in the first place, and then the need
>to downcast never arises, when our thoughts wander in that 
>direction one can be sure we are not thinking virtuously,
>and perhaps the design itself is flawed.
> ....

In article <1992Jul24.143359.3602@advtech.uswest.com> glw@io.uswest.com (Glenn  
Williams) replies:
>
> You have stated all this before, and every time you do, you fail to provide
> any examples of how you would design without downcasting. 
> 
> So, as I asked for earlier, let's have an example of a properly
> designed system.
> 
Indeed. Whenever I gave an example that demostrates the necessity of downcast,  
I was always considered to introduce a bad design, but I never get an example  
which is considered good and can solve the specific problem shown by my  
example. So, before blaming the "bad", show the good please.

Here, I'd like to use the example given by John's own:

> >(John MAX Skaller) writes: 
> >class Animal {
> >	int mate(Animal&);
> >};
> >class Dog : Animal {
> >	int mate (Animal&);
> >};
> 
> >We REALLY want Dog::mate(Dog&), but we can't have it.
>

Therefore you need RTTI and downcast, though a little bit too late to check the  
validation within the method body:

class Dog : Animal
{     int mate (Animal& a)
      { if (typeof(a) != Dog) return an_error_code;
        ...
      };
}
 
> >This is a flaw in Object Oriented Programming IMHO.

No. This is not the flaw of OOP. This the problem of the current C++ or some of  
other specific OO langauges and we need to solve it.

> >The solution requires multimethods which are inherently
> >functional.

Multimethods can never solve this problem. It would be very absurd to have the  
method "mate" multiplxed. We already know that it is impossible to have "cat  
mate dog", "fish mate bird", why we still want to try to mate these impossible  
conbination?

What we need is the covariant specification: to prevent the wrong combination  
by interface:

class Dog : Animal
{     int mate (thisclass&)
      {  ...
      };
}

Therefore, "cat mate dog" will be prohibited by the comipler. This is much  
better since we can prohibit the error earlier. RTTI is required when we do not  
know the actual type of the animals at compile time:

Animal & a1;
Animal & a2;

if (typeof(a1)==typeof(a2)) a1.mate(a2);

Before you condemn this as a bad design, answer the following question first:

Is it resonable to call "mate" through Animal interface?
--If yes, how do you prevent the wrong matches without RTTI?
--If no, why do you introduce the method "mate" in class Animal?

Now I give you an example that truely needs multiple dispatch.

class Animal
{  Animal * fight (Animal * a)
   {  if (a==0 && this->dead()) retuen 0;  // I use this-> for emphasis
      if (a==0 || a->dead()) return this;
      if (this->dead()) return a;
      if (this->over(a) && a->over(this))
      { this->kill(a);
        a->kill(this);
        retuen 0;
      }
      if (this->over(a))
      { this->kill(a);
        retuen this;
      }
      if (a->over(this))
      { a->kill(this);
        retuen a;
      }
      this->escape();
      a->ascape();
      return 0;
   }
};

and we have the following fights:

Animal * victor;
..
victor = wolf.fight (jackal);
victor = lynx.fight (victor);
victor = bull.fight (victor);
..

You'll suprise me if you say, okay, I don't care who is the winner, anyway,  
some animal or none. Then what's the purpose of the above codes? Just for some  
thing unknown, unknown forever?  You can say it is a bad design again, as  
easily as blowing off dust. But be aware, it is an example of your beloved  
multiple dispatch.

Now can you see the fact: both homo. (the example is "mate") and het. (the  
example is "fight") data structures need RTTI?

David Shang