From: mg@elan (Michael Golan)
Subject: Re: MI vs. SI
Organization: Princeton University, Dept. of Computer Science
Date: 21 Jan 93 15:36:37 GMT

pandrews@lovat.fmrco.com (Paul Andrews) writes:
>Totally agree. Why oh why oh why (:-)) do folks have such a downer on MI? 

Because
1) Most implementations are buggy. Maybe all those compiler writers are
   idiots. Maybe the idea too complex and not well understood/documented.
2) MI is hard to implement, hard to understand, hard to use correctly
3) MI can add bugs that are hard to detect
4) MI lead to bad design, where people make one class into 3 (inhereting
   from two smaller classes), just so that (1) and (2) could possibly be used
   independently, even when this is not likely or important
5) MI is commonly used as a hack to combine incompatible classes that 
   are badly designed to begin with. This might be nice and good in the 
   short-run, for older C++ classes designs. It is most likely bad in the 
   long run.
6) They were mostly needed before the templates-era, when classes where used
   in implementing template-concepts, e.g. when a class had to be derived
   from LIST to be on the list. Then, when you wanted to collect some
   functionality on a list, you had to use MI. You still have to do so,
   if your "LIST" is some complex class, that *combines* a collection-
   mechanism with other functionality. Most such designs are bad, and 
   using MI instead of fixing the design is a bad idea.
7) The complications to the language far out-weight the benefits, and it
   seems to have no end in sight. See dynamic_cast<Ouch>(Arr)
8) People abuse SI. I have seen many abstract classes with a field "type",
   which is set by each derived class and is checked at both levels.
   I consider this "cheating". The escape from such bad design is with MI,
   and I don't like it. Sure, you can tell me not to use/buy/touch such 
   code, but in the real world we have to compromise. Call us "Nazis", for
   we would like to force you into "good design" by limiting your options.
   This might hurt the super-smart designer, but improve the average programmer
   productivity. And yes, we are concerned with the later. The former can
   find a smart way to overcome the limits anyway, when required.
    
You claim that the NIH lib would be better off with MI, and that this is
"clear". I challenge you to a battle of wits (The princess's bride:-).
Show us an example! Many people in this group have been claiming for some time
now, that they are yet to have seen code where MI is needed when the 
classes are correctly designed (w/templates) from scratch. 
The last example on the net was a bank account class, from which credit and
debit accounts were derived, and then MI was used to combine their functions.
This is a typical bad example. How are the accounts stored on the disk?
wouldn't the code as a whole be shorter and easier to understand if
these where combined into one class? Only when real code is presented, to
achieve a real task, can we truely compare such approaches.

No doubt someone will tear this posting apart. Each point will be attacked
independently. I am sure I will be flamed for my own stupidity for not 
understanding the simple concepts behind MI, which are so obvious. You will
also tell us that soon, soon, MI will be implemented perfectly, and that you
have already used it in 100k lines project and it was indispensable.
Never the less, many people will remain steadfast in their believes in
many of the above claims. We don't believe this complexity is necessary,
and we would like a shorter reference manual!

Of course, we lost the battle a long time ago. Lets design ++C.

 Michael Golan
 mg@cs.princeton.edu
Xref: sparky comp.lang.c++:19957 comp.object:5071