Path: utzoo!utgpu!news-server.csri.toronto.edu!rutgers!cs.utexas.edu!uunet!odi!dlw From: dlw@odi.com (Dan Weinreb) Newsgroups: comp.object Subject: Re: Examples of Multiple Inheritance? Message-ID: <1990Dec9.064731.27957@odi.com> Date: 9 Dec 90 06:47:31 GMT References: <60700005@inmet> <77500069@m.cs.uiuc.edu> Reply-To: dlw@odi.com Organization: Object Design, Inc. Lines: 67 In-Reply-To: johnson@m.cs.uiuc.edu's message of 7 Dec 90 12:41:00 GMT In article <77500069@m.cs.uiuc.edu> johnson@m.cs.uiuc.edu writes: I could argue with this (and will). MI in the Lisp world is primarily composition of implementations. It is clear from Dan Halbert's description of MI in Trellis that MI is used there primarily for composition of interfaces. Thus, MI means different things to different people. In my experience with Lisp, it was often used for both purposes. Most of you are probably tired of hearing that I think that interface and implementation should be reused by different mechanisms; i.e. I think that types and classes are different, and that subclassing and subtyping should be different as well. MI of interface is important, but I would be happy to live without MI of implementation. In fact, I do! Perhaps you do, but "mixin" classes that modify behavior have turned out, many times, to be an elegant and simple way to express desired behavior. Of course they're not "necessary"; no programming language feature is. But they are a useful tool, and once you learn how to use the tool properly (modularly and tastefully), and when you build large systems with complex requirements, you often find that it is a good, appropriate tool. The question of providing separate concepts of "inheritance of protocol (specification)" and "inheritance of implementation" is one that we debated for some time in the design of Flavors. Generally I was in favor of introducing a separate concept of inheritance of specification, on the grounds that by forcing the programmer to see that it was something different, the programmer would end up understanding things better. Dave Moon, on the other hand, was opposed to the separation on the grounds that it would make Flavors more complex and hard to learn and verbose. I liked the idea that two classes might implement the same protocol, but not actually share any ancestors, because they might have totally independent implementations. Moon really didn't like the idea of having two separate hierarchies, one for protocols and one for implementations, for the reasons I cited. Another problem with the two-hierarchy design was that the interactive programming environment tools would get more numerous and complex. Instead, Moon preferred the idea of a single hierarchy. If there were multiple independent implementations, they'd both inherit from a purely-abstract class, that served to define the hierarchy but did not contribute any implementation. When CLOS was designed, based on Flavors and CommonLoops, the key designers (Bobrow, Moon, Kiczales, et. al.) decided against introducing the distinction. I can't speak for their reasons. I believe that Dan Halbert once told me that the Trellis designers spent a lot of time considering the same question, and decided that separating the two concepts would result in unacceptably excessive complexity in the language design, and be too hard for programmers to understand. I believe the idea of having two different hierarchies was also something they wanted to avoid. Note: I might be expressing this poorly, since I'm trying to remember a short remark from years back, and I am by no means a Trellis expert. C++, of course, is like Flavors too: one hierarchy, and you use an abstract class that contributes no implementation if you have independent implementations of a protocol. I'm also not exactly sure that the two-way decision that you are talking about is exactly the same as the one that Moon and I debated, nor the one that the Trellis designers considered. There are a lot of possible language designs, not just two choices. So I hope I'm not promulgating any misunderstandings.