tim@efi.com (Tim Maroney) (07/03/90)
The people doing the MPW compilers seem to think that multiple inheritance is not important. It's not possible at all in Object Pascal, and apparently is impossible to use in real (handle-based) applications in C++. I think this is a cavalier attitude. I've only been using Object Pascal for a couple of months now, and my only earlier OOP experience was with a flavored dialect of Franz Lisp many years ago; but I have already encountered a number of cases where the lack of multiple inheritance imposes inelegant solutions. The "seaplane" analogy seems to be a frivolous way of dismissing this important technique. First case: Extending a class library. Suppose that programmer A adds good, general Windows menu support to MacApp. There are basically two ways of doing this. The first is to create a class library add-on providing a number of methods which are supposed to be called at various points in other deveopers' applications. The other is to create a subclass of TApplication that calls all these methods at the appropriate places. In the first solution, the developers using this code have a considerably greater burden in terms of documentation-reading and error avoidance and code modification; in the second solution, developers only need to make their applications sub-classes of the sub-classed TApplication, a one-word code change. Obviously the second solution is cleaner. But now suppose someone else takes the same approach to add, say, walk-through keyboard-oriented menus. OOPs! You can't make your application a subclass of *both* TWinMenuApplication and TWalkMenuApplication. There's no multiple inheritance. One or the other has to revert to the bad old "insert tab A into routine B" solution. Second case: Managing a list of largely dissimilar objects that have some common behavior. For instance, suppose that you are keeping a list of objects, some of which are TViews, some of which are TCommands, some of which are on your own inheritance tree from TObject. They can't be given common methods, because you can't make something a descendant of both TView and your common-methods class. Multiple inheritance would make for a very clean solution. Instead, you have to put in type-coercion case statements using class ids, or have each list entry associated with a separate object sub-classed on a per-list-element-type basis which implements the common methods while knowing what type of object the message is being passed on to. Both of these are very clunky solutions to a problem which is cleanly solved by multiple inheritance. If I were in the languages groups at either Apple or Symantec, I would consider it a high priority to bring multiple inheritance into Object Pascal and to make it usable with C++ or Object C. Elegant solutions are not a luxury. Clean code is more maintainable and less buggy. If someone has a personal dislike of multiple inheritance and doesn't want to use it, fine. Adding it to the language imposes no such burden on these people. But omitting it does impose a burden on those of us in the other camp.
casseres@apple.com (David Casseres) (07/04/90)
In article <1990Jul2.181147.1672@efi.com> tim@efi.com (Tim Maroney) writes: > The people doing the MPW compilers seem to think that multiple > inheritance is not important. It's not possible at all in Object > Pascal, and apparently is impossible to use in real (handle-based) > applications in C++. I think this is a cavalier attitude. One clarification and two comments. The clarification: C++ on the Mac does not allow multiple inheritance for subclasses of THandleObject; but it can be used with all other classes. It doesn't matter whether the application uses THandleObject subclasses in addition. Note that it is not necessary for everything to be handle-based. First comment: The restriction on THandleObject subclasses and multiple inheritance is due to serious implementation difficulties that have been explained in this group, not to a cavalier attitude. Second comment: There is some justification for a cavalier attitude about multiple inheritance, just as there is justification for wanting it very badly in some cases. Brian Bechtel sums it up very well in saying "Multiple inheritance is the GOTO of the 1990's." It is tremendously powerful, lets you do any damn thing you like, elegantly solves certain problems, leads to utterly obscure code, and invites massive abuse that can cause enormous damage to the integrity of code. In my own limited experience with C++, I have found that a redesign of the hierarchy always leads to cleaner, more elegant code than multiple inheritance. But then, I'm not using a hierarchy containing a lot of libraries produced by other people. If I were, I might want to use a lot of multiple inheritance; but on the other hand, I think that in that situation what I would *really* want is source code for all the libraries so I could re-implement them to suit my purposes! That, not any lack of features, is the problem with any OOPS that gives you only compiled libraries instead of source code. David Casseres Exclaimer: Hey!
rmh@apple.com (Rick Holzgrafe) (07/04/90)
In article <8967@goofy.Apple.COM> casseres@apple.com (David Casseres) writes: > [...] I'm not using a hierarchy containing a lot of > libraries produced by other people. If I were, I might want to use a lot > of multiple inheritance; but on the other hand, I think that in that > situation what I would *really* want is source code for all the libraries > so I could re-implement them to suit my purposes! Well, I like source too. But one of the best features of OOP is re-usable modules *without* having to hack the source. ========================================================================== Rick Holzgrafe | {sun,voder,nsc,mtxinu,dual}!apple!rmh Software Engineer | AppleLink HOLZGRAFE1 rmh@apple.com Apple Computer, Inc. | "All opinions expressed are mine, and do 20525 Mariani Ave. MS: 77-A | not necessarily represent those of my Cupertino, CA 95014 | employer, Apple Computer Inc."
lins@Apple.COM (Chuck Lins) (07/04/90)
In article <8967@goofy.Apple.COM> casseres@apple.com (David Casseres) writes: [ a lot of commentary deleted; perhaps relevant ] >Brian Bechtel sums it up very well in saying >"Multiple inheritance is the GOTO of the 1990's." I couldn't agree more. Eventually some big name CS prof will probably write an article called "Multiple Inheritance Considered Harmful". There'll be a big, huge, mundo flame war over it. If people go ga-ga over MI the way they have so far with objects, we'll end up with "spagetti-objects" even worse than the spagetti code produced using GOTO. (An even worse construct was COBOL's ALTER verb but we won't get into that! :) Don't get me wrong, I think the object- oriented paradigm has a lot to offer and is one of the more valuable techniques in the programmer's arsenal to come around in years. But I was a neophyte programmer during the 'structured programming revolution'. And all the claims of 'object-this' and 'object-that' sound very similar to the 'structured-this' and 'structured-that' of the 1970's. Lots of hype and claims that can't be substantiated. So I know I'd love to see any empirical evidence that shows MI reduces not only new development costs but also the cost of maintenance. Please post your references to those journal articles today 'cause I'd love to be enlightened. -- Chuck Lins | "Is this the kind of work you'd like to do?" Apple Computer, Inc. | -- Front 242 20525 Mariani Avenue | Internet: lins@apple.com Mail Stop 37-BD | AppleLink: LINS@applelink.apple.com Cupertino, CA 95014 | "Self-proclaimed Object Oberon Evangelist" The intersection of Apple's ideas and my ideas yields the empty set.
casseres@apple.com (David Casseres) (07/04/90)
[I wrote] > ...C++ on the Mac does not allow multiple inheritance for subclasses > of THandleObject... Sloppy, sloppy. I should have said "for subclasses of HandleObject or PascalObject." David Casseres Exclaimer: Hey!
amanda@mermaid.intercon.com (Amanda Walker) (07/04/90)
In article <42616@apple.Apple.COM>, lins@Apple.COM (Chuck Lins) writes: > If people go ga-ga over MI the way they have so > far with objects, we'll end up with "spagetti-objects" even worse than the > spagetti code produced using GOTO. There are times when multiple inheritance can be used to produce very elegant code. However, object-oriented programming doesn't enforce disciplined programming any more than anything else. Used properly, multiple inheritance can be very useful in decomposing problems over orthgonal axes (for example, take a look at the "mixin" concept in several Lisp object platforms). Used improperly, you can end up with the "it's a floor wax AND a dessert topping" effect... It all depends on the programmer. -- Amanda Walker InterCon Systems Corporation -- "I can only assume this is not the first-class compartment." --Hitchhiker's Guide to the Galaxy
lins@Apple.COM (Chuck Lins) (07/06/90)
In article <2691908E.738C@intercon.com> amanda@mermaid.intercon.com (Amanda Walker) writes: >In article <42616@apple.Apple.COM>, lins@Apple.COM (Chuck Lins) writes: >> If people go ga-ga over MI the way they have so >> far with objects, we'll end up with "spagetti-objects" even worse than the >> spagetti code produced using GOTO. > >There are times when multiple inheritance can be used to produce very elegant >code. And there are times when I can use assembly language and the evil GOTO to write very elegant code too. >Used properly, multiple inheritance >can be very useful in decomposing problems over orthgonal axes (for example, >take a look at the "mixin" concept in several Lisp object platforms). Used >improperly, you can end up with the "it's a floor wax AND a dessert topping" >effect... Symbolic Lisp Machines have a wonderful class in the UI called a Listener. It inherits from 26 different classes, sometimes through multiple different paths in the inheritance graph. It's impossible to subclass properly or even figure out how to take advantage of its functionality (in case one wanted to do the same thing). -- Chuck Lins | "Is this the kind of work you'd like to do?" Apple Computer, Inc. | -- Front 242 20525 Mariani Avenue | Internet: lins@apple.com Mail Stop 37-BD | AppleLink: LINS@applelink.apple.com Cupertino, CA 95014 | "Self-proclaimed Object Oberon Evangelist" The intersection of Apple's ideas and my ideas yields the empty set.
tim@efi.com (Tim Maroney) (07/06/90)
In article <1990Jul2.181147.1672@efi.com> tim@efi.com (Tim Maroney) writes: >> The people doing the MPW compilers seem to think that multiple >> inheritance is not important. It's not possible at all in Object >> Pascal, and apparently is impossible to use in real (handle-based) >> applications in C++. I think this is a cavalier attitude. In article <8967@goofy.Apple.COM> casseres@apple.com (David Casseres) writes: >One clarification and two comments. The clarification: C++ on the Mac >does not allow multiple inheritance for subclasses of THandleObject; but >it can be used with all other classes. It doesn't matter whether the >application uses THandleObject subclasses in addition. Note that it is >not necessary for everything to be handle-based. I haven't used the C++ MacApp, but isn't it handle-based? >First comment: The restriction on THandleObject subclasses and multiple >inheritance is due to serious implementation difficulties that have been >explained in this group, not to a cavalier attitude. Not really. I have yet to run into a programming model using pointers into nonrelocatable blocks that couldn't be rephrased in terms of offsets into relocatable blocks. It may require some work on the part of the compiler developer -- since they didn't do it right the first time -- but it's hardly a serious implementation difficulty. It's a well-known programming practice. >Second comment: There is some justification for a cavalier attitude about >multiple inheritance, just as there is justification for wanting it very >badly in some cases. Brian Bechtel sums it up very well in saying >"Multiple inheritance is the GOTO of the 1990's." It is tremendously >powerful, lets you do any damn thing you like, elegantly solves certain >problems, leads to utterly obscure code, and invites massive abuse that >can cause enormous damage to the integrity of code. Hmm. Power can always be abused. The more power you give a developer, the more power she has to write either elegant or inelegant code. There are very few cases in which the power of a GOTO leads to cleaner code (certain software implementations of finite-state machines are all that springs to mind), but I don't think that multiple inheritance is one of these inherently risky powers. Writing a better programming language is a matter of psychology. How cleanly do the programming language's concepts and tools map into the way that humans inherently view objects and tasks? A loop construct is closer to the ordinary human way of seeing tasks than is a GOTO. If we're telling soemone how to do something, we might say "do this ten times" or "keep doing it until the film is dry" or something of that kind; we are much less likely to say "go back to step 5". Object programming is another step towards more human conceptualization of tasks. The whole notion of class inheritance is based on the human division of phenomena into categories and subcategories. Because of this, object programming can lead to solutions that seem more "natural" and "clean". But humans also naturally perceive categories in terms of multiple inheritance; that is, many phenomena are routinely considered members of classes which are not descendants of each other. Because of this, multiple inheritance is a step closer to human concepts, unlike GOTO which is an artificial contrivance unrelated to normal human modes of perception. So I don't think the a comparison between multiple inheritance and GOTO is accurate. If anything, they are opposites. >In my own limited experience with C++, I have found that a redesign of the >hierarchy always leads to cleaner, more elegant code than multiple >inheritance. But then, I'm not using a hierarchy containing a lot of >libraries produced by other people. If I were, I might want to use a lot >of multiple inheritance; but on the other hand, I think that in that >situation what I would *really* want is source code for all the libraries >so I could re-implement them to suit my purposes! That, not any lack of >features, is the problem with any OOPS that gives you only compiled >libraries instead of source code. I don't agree. You shouldn't have to modify source code to use an object library. It leads to an immediate drop in confidence in the code's reliability, which is to say, when you get a bug, you never know whether it's because of code you've added or because of the changed object library. It's possible that you've violated subtle assumptions of the library, so you have to spend a great deal of time just plowing through source code that you should never need to see. If I have one big complaint with MacApp so far, it is precisely that you have to read the source code all the time. If you have to change the code to do things, then this problem gets even worse.
tim@efi.com (Tim Maroney) (07/06/90)
In article <8967@goofy.Apple.COM> casseres@apple.com (David Casseres) writes: >>Brian Bechtel sums it up very well in saying >>"Multiple inheritance is the GOTO of the 1990's." In article <42616@apple.Apple.COM> lins@Apple.COM (Chuck Lins) writes: >But I was a neophyte >programmer during the 'structured programming revolution'. And all the claims >of 'object-this' and 'object-that' sound very similar to the 'structured-this' >and 'structured-that' of the 1970's. Lots of hype and claims that can't be >substantiated. So I know I'd love to see any empirical evidence that shows >MI reduces not only new development costs but also the cost of maintenance. >Please post your references to those journal articles today 'cause I'd love to >be enlightened. You would? Fine, then read my message, and if you can come up with cleaner solutions to the two problems I described in detail there, solutions that require neither multiple inheritance nor modification of object library source code, by all means post your enlightened, empirical rebuttal. If you can't come up with good non-MI, non-source-code-changing solutions, though, then please don't just pretend that the examples don't exist. Ignoring counterexamples is definitely not any kind of empiricism that *I* know of....
shebanow@Apple.COM (Andrew Shebanow) (07/06/90)
In article <1990Jul2.181147.1672@efi.com> tim@efi.com (Tim Maroney) writes: >The people doing the MPW compilers seem to think that multiple >inheritance is not important. It's not possible at all in Object >Pascal, and apparently is impossible to use in real (handle-based) >applications in C++. I think this is a cavalier attitude. I've only >been using Object Pascal for a couple of months now, and my only >earlier OOP experience was with a flavored dialect of Franz Lisp many >years ago; but I have already encountered a number of cases where the >lack of multiple inheritance imposes inelegant solutions. The >"seaplane" analogy seems to be a frivolous way of dismissing this >important technique. Although it might seem hard to believe given the inflammatory tone of Tim's missive, there are many people here at Apple who think that MI is important. I suggest that you all read the article by David Goldsmith and Jack Palevich in the latest issue of d e v e l o p for some useful MI guidelines that we use internally. The limitations on the use of MI in handle based objects are caused by C++'s object model, and not by a lack of concern on the part of Apple's engineers. If anyone can figure out a good way to solve this problem without rewriting all of CFront, we would of course be very interested in hearing about it. Object Pascal doesn't support MI primarily for historical reasons. The language wasn't designed with MI in mind, and adding MI to it would be a decidedly non-trivial change. However, Apple's Advanced Technology Group is looking at doing an updated version of the Object Pascal language - for more information, see the last issue of the MacApp Developer's Association publication, Frameworks". Andy Shebanow Apple Computer, Inc.
amanda@mermaid.intercon.com (Amanda Walker) (07/06/90)
In article <1990Jul5.223032.14604@efi.com>, tim@efi.com (Tim Maroney) writes: > I have yet to run into a programming model using pointers > into nonrelocatable blocks that couldn't be rephrased in terms of > offsets into relocatable blocks. It may require some work on the part > of the compiler developer -- since they didn't do it right the first > time -- but it's hardly a serious implementation difficulty. In the abstract, you're quite right. However, C++ is a little trickier, thanks (?) to it's heritage from C. In particular, object references are generally treated as being "special" kinds of pointers. Technically, I don't see anything in the language that requires that object references and pointers be the same size, but I suspect that it would be extremely difficult to retrofit such a change into an existing C++ compiler such as cfront (which is what Apple's C++ is based on). Now, I'm all for a from-scratch C++ compiler--one that could handle 64-bit object references and spit out object files instead of C code, but I'd rather have a solid port of cfront to play with until such a beast exists. Even what we've already got is a noticeable improvement over vanilla C... -- Amanda Walker <amanda@intercon.com> InterCon Systems Corporation -- "I can only assume this is not the first-class compartment." --Hitchhiker's Guide to the Galaxy
lbaum@bcsaic.UUCP (Larry Baum) (07/06/90)
In article <42665@apple.Apple.COM> lins@Apple.COM (Chuck Lins) writes:
:
: >Used properly, multiple inheritance
: >can be very useful in decomposing problems over orthgonal axes (for example,
: >take a look at the "mixin" concept in several Lisp object platforms). Used
: >improperly, you can end up with the "it's a floor wax AND a dessert topping"
: >effect...
: Symbolic Lisp Machines have a wonderful class in the UI called a
: Listener. It inherits from 26 different classes, sometimes through
: multiple different paths in the inheritance graph. It's impossible
: to subclass properly or even figure out how to take advantage of its
: functionality (in case one wanted to do the same thing).
It might be impossible for you, but it certainly isn't in general. I
think the key point is that without multiple inheritance, Symbolics
probably wouldn't have come up with this class which you admit is
wonderful.
The flavor components of Lisp-Listener are:
W:LISP-LISTENER
W:LISTENER-MIXIN
W:INTERACTOR-MIXIN
W:LISTENER-MIXIN-INTERNAL
W:PROCESS-MIXIN
SI:STANDARD-VALUE-ENVIRONMENT-MIXIN
W:WINDOW
W:BORDERS-MIXIN
W:LABEL-MIXIN
W:ESSENTIAL-LABEL-MIXIN
W:MARGIN-HACKER-MIXIN
W:MINIMUM-WINDOW
W:ESSENTIAL-EXPOSE
W:ESSENTIAL-ACTIVATE
W:ESSENTIAL-SET-EDGES
W:ESSENTIAL-MOUSE
W:STREAM-MIXIN
SI:DISPLAY-INPUT-EDITOR
SI:INTERACTIVE-STREAM
SI:LINE-OUTPUT-STREAM-MIXIN
SI:CHARACTER-STREAM
SI:BIDIRECTIONAL-STREAM
SI:INPUT-STREAM
W:SELECT-MIXIN
W:GRAPHICS-MIXIN
W:ESSENTIAL-WINDOW
W:SHEET
SI:OUTPUT-STREAM
SI:STREAM
GRAPHICS:RASTER-GRAPHICS-MIXIN
GRAPHICS::DRAWING-STATE-GRAPHICS-MIXIN
GRAPHICS:STANDARD-GRAPHICS-MIXIN
W:GRAPHICS-COMPATIBILITY-MIXIN
FLAVOR:VANILLA
Without going thru each one individually, each of these mixins provides
different sets of behaviors which are for the most part orthogonal; e.g.
Listener-mixin makes the lisp listener a separate process with a
READ-EVAL-PRINT loop and the ability to understand command processor
commands.
Borders mixin takes care of how and when to draw or redraw borders on
windows, label-mixin takes care of window labels, etc.
It is true that often a method (i.e. the function that runs in response
to a message) is a complex combination of individual methods contributed
from each mixin and it can be difficult (but certainly not impossible)
to figure out how they combine. That is why Symbolics includes a
workbench of extremely powerful tools such as the Flavor Examiner,
Inspector, etc. I would certainly agree that object-oriented languages
permitting multiple inheritance should be bundled with such powerful
tools. Of course, it is multiple inheritance that makes the building
of those tools much more feasible.
--
Larry Baum
Advanced Technology Center
Boeing Computer Services uucp: uw-beaver!bcsaic!lbaum
(206) 865-3365 internet: lbaum@atc.boeing.com
dorner@pequod.cso.uiuc.edu (Steve Dorner) (07/07/90)
In article <1990Jul5.223032.14604@efi.com> tim@efi.com (Tim Maroney) writes: >A loop construct is >closer to the ordinary human way of seeing tasks than is a GOTO. If >we're telling soemone how to do something, we might say "do this ten >times" or "keep doing it until the film is dry" or something of that >kind; we are much less likely to say "go back to step 5". As long as we're waxing philosophical: I think I'm far more likely to tell someone, "if the film isn't dry, do it again." And "start over from the beginning" is also very common. Both of these are very much GOTO's. I think loops and such are in fact very UNnatural. They take quite a bit of getting used to, which is not a comment on their utility or elegance. The same may be said of OOPL's; they're darn weird at first. -- Steve Dorner, U of Illinois Computing Services Office Internet: s-dorner@uiuc.edu UUCP: {convex,uunet}!uiucuxc!dorner
lsr@Apple.COM (Larry Rosenstein) (07/07/90)
In article <1990Jul2.181147.1672@efi.com> tim@efi.com (Tim Maroney) writes: > >First case: Extending a class library. Suppose that programmer A adds >good, general Windows menu support to MacApp. There are basically two >ways of doing this. The first is to create a class library add-on >providing a number of methods which are supposed to be called at >various points in other deveopers' applications. The other is to That's how I would do this in the context of MacApp. I would also, provide a subclass of TApplication that uses these call, for programmers that can take advantage of it. (Look at the graphics building block that I implemented in "Programming with MacApp".) >application a subclass of *both* TWinMenuApplication and >TWalkMenuApplication. There's no multiple inheritance. One or the Multiple inheritance doesn't automatically solve this problem. There can be conflicts between the base classes, which the programmer has to resolve. In those cases, you are back to the first alternative above (essentially). >Second case: Managing a list of largely dissimilar objects that have >some common behavior. For instance, suppose that you are keeping a You can never manage lists of totally dissimilar objects. The objects must have some commonality, otherwise you are foced to test their type when you take them out of the collection. In a typed language, this means that they have a common base class. (In an untyped language such as Smalltalk, 2 classes can implement the same protocol without being related in the class hierarchy.) >descendant of both TView and your common-methods class. Multiple >inheritance would make for a very clean solution. Instead, you have to >put in type-coercion case statements using class ids, or have each list >entry associated with a separate object sub-classed on a >per-list-element-type basis which implements the common methods while >knowing what type of object the message is being passed on to. Both of Let's suppose you're doing an interface builder program, so you want to make a list of the interface objects in the program (views, commands, etc.) It's not clear that MI makes for a cleaner solution. You define a InterfaceElement class and subclass View, Command, etc. to mixin InterfaceElement. But you still have the problem that the only things you can do to the object when you take it out of the list are the method defined in InterfaceElement. Suppose InterfaceElement has A Draw() method. That's fine, but it means that you have to override Draw for each of the subclasses that you create. This isn't much different from defining subclasses of InterfaceElement such as ViewElement, CommandElement, ... each of which contains a reference to the View, Command, ... You have to define the same number of classes, and methods although you do end up with twice the number of objects. In some sense it is cleaner because the objects that relate to the interface builder are separate from the objects that are implementing the interface. Also, you can use C++ operator overloading to make the use of the surrogate objects easier. (ViewElement can define operator View, for example.) In both implementations, you have to do coercions when you remove an object from the list, if you want to use any methods defined by View, Command, etc. >doesn't want to use it, fine. Adding it to the language imposes no >such burden on these people. But omitting it does impose a burden This isn't necessarily true. In the standard C++ implementation (as you get from AT&T) you pay some of the cost of MI, even if you don't use it. All the virtual tables are twice as large, and the method dispatching protocol takes MI into account even if you don't use it. That's why MPW C++ has a built-in SingleObject class, which implements the old (CFront 1.2) dispatching scheme. I'm sure one could design a runtime system that implements MI without creating pointers to the middle of an object (and thereby allowing HandleObjects to use MI), and without placing a runtime burden on programmers than don't use MI. This is a big job, however, especially if you want to maintain semantic compatibility with AT&T's implementation of C++. (You have to worry about object casts, and virtual base classes, for example.) -- Larry Rosenstein, Object Specialist Apple Computer, Inc. 20525 Mariani Ave, MS 46-B Cupertino, CA 95014 AppleLink:Rosenstein1 domain:lsr@Apple.COM UUCP:{sun,voder,nsc,decwrl}!apple!lsr
beard@ux1.lbl.gov (Patrick C Beard) (07/08/90)
In article <2691908E.738C@intercon.com> amanda@mermaid.intercon.com (Amanda Walker) writes: #In article <42616@apple.Apple.COM>, lins@Apple.COM (Chuck Lins) writes: #> If people go ga-ga over MI the way they have so #> far with objects, we'll end up with "spagetti-objects" even worse than the #> spagetti code produced using GOTO. # #There are times when multiple inheritance can be used to produce very elegant #code. However, object-oriented programming doesn't enforce disciplined #programming any more than anything else. Used properly, multiple inheritance #can be very useful in decomposing problems over orthgonal axes (for example, #take a look at the "mixin" concept in several Lisp object platforms). Used #improperly, you can end up with the "it's a floor wax AND a dessert topping" #effect... # #It all depends on the programmer. This is the most relevant comment that has been made so far. Just like power tools that carpenters use, Multiple Inheritance isn't something to be used casually. You really do have to know what you are doing. I would say that most programmers aren't at the level of expertise in object programming to know what to do with MI. I know I'm not there yet. But when I reach that level, I know that I want the option to try it out. The biggest problem with books on C++ and books on object programming in general, is that there aren't any clear-cut examples that show the perfect application of MI. So it's kind of a solution waiting for a problem. Just as with object programming vs. procedural programming, it's a good idea to use the right tool for the right job. By the way, has anyone read Meyer's book on Eiffel? Eiffel has been touted (by him and others) as having the cleanest implementation of MI of any language so far. I would hope somebody is working on an implementation for the Macintosh. ------------------------------------------------------------------------------- - Patrick Beard, Macintosh Programmer (beard@lbl.gov) - - Berkeley Systems, Inc. ".......<dead air>.......Good day!" - Paul Harvey - -------------------------------------------------------------------------------
mnykanen@cc.helsinki.fi (07/09/90)
In article <1990Jul5.223032.14604@efi.com>, tim@efi.com (Tim Maroney) writes: > Object programming is another step towards more human conceptualization > of tasks. The whole notion of class inheritance is based on the human > division of phenomena into categories and subcategories. Because of Are you saying that hierarchicality is a fundamental property of human thought? I think we western 'scientists' have just been educated in the Aristotelian tradition (although A. himself would have stuck with single inheritance.. :-) ). This is what you get when making philo/psychological commitments based on programming practise; conceptually OOP is a mess. -- Matti Nyk{nen CS Student at Helsinki U, Finland email: mnykanen@cc.helsinki.FI The best opinions available; get them while they're hot!
jimm@amiga.UUCP (Jim Mackraz) (07/10/90)
(Rick Holzgrafe) writes:
)Well, I like source too. But one of the best features of OOP is re-usable
)modules *without* having to hack the source.
Traditionally? I thought part of Smalltalk was the browsing of class source
code, changing it as needed.
I think it's pretty clear that you can't extend a class by inheritance
in ways that were not anticipated by the author of the class. If the
"method" hooks you can override aren't in the right places, you are stuck.
I expect that making profound changes in a subclass will often require the
source to the superclass, and almost as often only be feasible if you
can modify that source.
jimm
--
-------------------------------------------------- - opinions by me
"This voice console is a *must*. I press Execute.
`Hello, I know that you've been feeling tired.
I bring you love and deeper understanding.' " -lyrics by Kate Bush
amanda@mermaid.intercon.com (Amanda Walker) (07/10/90)
Anyone who is doing much work with MPW C++ should probably try to scrape up a copy of the "Unofficial C++ Style Guide" that David Goldsmith wrote up. I know that there's a copy on "A Disc Called Wanda," but I don't know if it's available in some other fashion for people without CD-ROM players. It's aimed primarily at people new to C++, but it's got a number of very useful guidelines, including stuff about keeping multiple inheritance from producing spaghetti code. -- Amanda Walker <amanda@intercon.com> InterCon Systems Corporation
rmh@apple.com (Rick Holzgrafe) (07/12/90)
In article <5991@amiga.UUCP> jimm@amiga.UUCP (Jim Mackraz) writes: > (Rick Holzgrafe) writes: > )Well, I like source too. But one of the best features of OOP is re-usable > )modules *without* having to hack the source. > > Traditionally? I thought part of Smalltalk was the browsing of class source > code, changing it as needed. > > I think it's pretty clear that you can't extend a class by inheritance > in ways that were not anticipated by the author of the class. If the > "method" hooks you can override aren't in the right places, you are stuck. You're right, and it's why I said "I like source too". It's not easy to write a class so that all reasonable extensions can easily be made by subclassing. (I know; I've tried.) But that's the *goal* of OOP (well, one of them anyway :-). Easily sub-classable classes increase the productivity of the developers who use them. Try hard to write classes whose users won't need source. Then give them source anyway. ========================================================================== Rick Holzgrafe | {sun,voder,nsc,mtxinu,dual}!apple!rmh Software Engineer | AppleLink HOLZGRAFE1 rmh@apple.com Apple Computer, Inc. | "All opinions expressed are mine, and do 20525 Mariani Ave. MS: 77-A | not necessarily represent those of my Cupertino, CA 95014 | employer, Apple Computer Inc."
lsr@Apple.COM (Larry Rosenstein) (07/12/90)
In article <5991@amiga.UUCP> jimm@superman.UUCP (Jim Mackraz) writes: > >Traditionally? I thought part of Smalltalk was the browsing of class source >code, changing it as needed. That's the way Smalltalk has been traditionally, but even then some parts aren't available in source form. (I think that the number of such things in Smalltalk/V is even larger; for example their compiler.) >I think it's pretty clear that you can't extend a class by inheritance >in ways that were not anticipated by the author of the class. If the >"method" hooks you can override aren't in the right places, you are stuck. Then the class wasn't designed properly. In a well-designed class, each method does only 1 function, so it is easy override the function you need to change. On the other hand, if a method does 2 things and you need to override only one of them, then you have to re-implement something you shouldn't need to. >I expect that making profound changes in a subclass will often require the >source to the superclass, and almost as often only be feasible if you >can modify that source. I'm sure that you can always do this such that the class won't serve your needs. But in that case, you are outside the design center of the class. It's the same as extending any tool beyond its intended use. The challenge in designing a class is to make its applicability as broad as possible. There are class libraries on the market that ship in object code-only form. (The same as there are subroutine libraries that ship in object form.) It should be possible to find out whether source is a requirement for a class library. -- Larry Rosenstein, Object Specialist Apple Computer, Inc. 20525 Mariani Ave, MS 46-B Cupertino, CA 95014 AppleLink:Rosenstein1 domain:lsr@Apple.COM UUCP:{sun,voder,nsc,decwrl}!apple!lsr
lsr@Apple.COM (Larry Rosenstein) (07/12/90)
In article <2699F590.3593@intercon.com> amanda@mermaid.intercon.com (Amanda Walker) writes: >Anyone who is doing much work with MPW C++ should probably try to scrape >up a copy of the "Unofficial C++ Style Guide" that David Goldsmith wrote >up. I know that there's a copy on "A Disc Called Wanda," but I don't know It's in develop #2. -- Larry Rosenstein, Object Specialist Apple Computer, Inc. 20525 Mariani Ave, MS 46-B Cupertino, CA 95014 AppleLink:Rosenstein1 domain:lsr@Apple.COM UUCP:{sun,voder,nsc,decwrl}!apple!lsr
casseres@apple.com (David Casseres) (07/13/90)
In article <9093@goofy.Apple.COM> rmh@apple.com (Rick Holzgrafe) writes: > Try hard to write classes whose users won't need source. Then give them > source anyway. Since I made the remark that started this sub-thread, I should add that I heartily agree with the above. Let me try a better way of saying what I was getting at in the first place: I would rather be grubbing around and rewriting source code to figure out how to make a poorly designed class do what I want, than putting together a pot of spaghetti made out of poorly designed classes and multiple inheritance. Obviously, it is best if we don't have any poorly designed classes to deal with, but life is not really like that. Even with well-designed classes there is *sometimes* a situation where you want a new Class X to be able to do things like both Class A and Class B. My preferred way of dealing with this is to let X be a subclass of A and let each instance of X contain an instance of B. In some sense this is not as elegant as multiple inheritance, but in another sense it is more elegant: it encapsulates the problem much more effectively -- X and its subclasses need not worry about which of their parents they are inheriting from. David Casseres Exclaimer: Hey!
tim@efi.com (Tim Maroney) (07/14/90)
In article <1990Jul2.181147.1672@efi.com> tim@efi.com (Tim Maroney) writes: >>The people doing the MPW compilers seem to think that multiple >>inheritance is not important. It's not possible at all in Object >>Pascal, and apparently is impossible to use in real (handle-based) >>applications in C++. I think this is a cavalier attitude. I've only >>been using Object Pascal for a couple of months now, and my only >>earlier OOP experience was with a flavored dialect of Franz Lisp many >>years ago; but I have already encountered a number of cases where the >>lack of multiple inheritance imposes inelegant solutions. The >>"seaplane" analogy seems to be a frivolous way of dismissing this >>important technique. In article <9007@goofy.Apple.COM> shebanow@Apple.COM (Andrew Shebanow) writes: >Although it might seem hard to believe given the inflammatory tone >of Tim's missive, there are many people here at Apple who think >that MI is important. What I find hard to believe is that anyone would seriously call the above "inflammatory". There seems to be an attitude that any criticism of Apple technical policy is inherently inflammatory, even if its language is moderate and its arguments carefully drawn. Is it really "inflammatory" to call an attitude "cavalier" and an argument "frivolous"? If so, how would it be possible to make any criticism that was not "inflammatory"? >The limitations on the use of MI in handle based objects are caused >by C++'s object model, and not by a lack of concern on the part >of Apple's engineers. If anyone can figure out a good way to solve >this problem without rewriting all of CFront, we would of course be >very interested in hearing about it. A number of small developers have come out with native C++ compilers for DOS, I believe. I doubt that writing a compiler would be a serious strain on Apple's bountiful development resources. cfront is a slow interim solution, which you'll have to break with sooner or later. However, I don't know that the best way to solve the problem involves handle+offset ways of accessing objects, as suggested by a few people here. Suppose that an object begins with a class offset table, consisting of an array of pairs (class id, offset to members). Then the generated code uses a double-offset operation to get to the members of the class it's dealing with. There is a small performance penalty, but it keeps the model fairly clean, and you only have to do the table lookup once per object per method. >Object Pascal doesn't support MI primarily for historical reasons. >The language wasn't designed with MI in mind, and adding MI >to it would be a decidedly non-trivial change. However, Apple's >Advanced Technology Group is looking at doing an updated >version of the Object Pascal language - for more information, >see the last issue of the MacApp Developer's Association publication, >Frameworks". Perhaps we should subscribe to it. Object Pascal has two major deficiencies. One is the lack of multiple inheritance; the other is the lack of information hiding (private methods and members). Is the ATG also looking at adding information hiding?
tim@efi.com (Tim Maroney) (07/14/90)
In article <1990Jul5.223032.14604@efi.com> tim@efi.com (Tim Maroney) writes: >>A loop construct is >>closer to the ordinary human way of seeing tasks than is a GOTO. If >>we're telling soemone how to do something, we might say "do this ten >>times" or "keep doing it until the film is dry" or something of that >>kind; we are much less likely to say "go back to step 5". In article <1990Jul6.182948.12005@ux1.cso.uiuc.edu> dorner@pequod.cso.uiuc.edu (Steve Dorner) writes: >As long as we're waxing philosophical: > >I think I'm far more likely to tell someone, "if the film isn't dry, >do it again." And "start over from the beginning" is also very common. >Both of these are very much GOTO's. Not at all! They are very much loop instructions, and very much *not* GOTO's. Each of them carries semantic information informing the person that this is an instruction to repeat something. I suggest re-reading the above in this light. "Go to step 5" carries no such semantic information. It is merely notational, devoid of inherent meaning. >I think loops and such are in fact very UNnatural. They take quite a bit >of getting used to, which is not a comment on their utility or elegance. >The same may be said of OOPL's; they're darn weird at first. I used to help quite a few people who were learning to program at my university. I really don't remember any of them having much trouble internalizing the concept of a loop, though some did have problems with some of the subtleties of particular programming language's *implementation* of loops -- particularly in Fortran and C.
tim@efi.com (Tim Maroney) (07/14/90)
In article <1990Jul5.223032.14604@efi.com>, tim@efi.com (Tim Maroney) writes: >> Object programming is another step towards more human conceptualization >> of tasks. The whole notion of class inheritance is based on the human >> division of phenomena into categories and subcategories. Because of In article <2742.26985429@cc.helsinki.fi> mnykanen@cc.helsinki.fi writes: >Are you saying that hierarchicality is a fundamental property of human >thought? Yes. Description inherently operates at various levels of abstraction. There are animals; there are dogs; there is my dog. If you know of languages or cultures which do not operate in this hierarchical fashion, I would like to hear about them (always interested in new ways of thinking!) >I think we western 'scientists' have just been educated in the >Aristotelian tradition (although A. himself would have stuck with single >inheritance.. :-) ). I can't claim to be a cultural anthropologist, but levels of abstraction in decription certainly precede Aristotle, and appear in cultures which were not influenced by Aristotle. Look at, say, the Trobriand Islanders' mythology. They have concepts both for particular animals, and for animals overall, and for types of animals; for people, for people of different genders, and for individual people; for spirits in general, for families of spirits, and for particular spirits. If you were doing a simulation of these concepts in an object language, you would represent them with superclass and subclass relationships. >This is what you get when making philo/psychological >commitments based on programming practise; conceptually OOP is a mess. Conceptually, our minds are a mess. Look at the syntax of natural language if you want to see a real mess. The question with a programming language is how close its mess approximates to our ordinary mess....
shebanow@Apple.COM (Andrew Shebanow) (07/17/90)
>What I find hard to believe is that anyone would seriously call the >above "inflammatory". There seems to be an attitude that any criticism >of Apple technical policy is inherently inflammatory, even if its >language is moderate and its arguments carefully drawn. Is it really >"inflammatory" to call an attitude "cavalier" and an argument >"frivolous"? If so, how would it be possible to make any criticism >that was not "inflammatory"? It isn't imflammatory to criticize Apple. There are plenty of people on the nets who criticize Apple all the time, and nobody bats an eye. Criticizing Apple for not supporting MI on handle based objects is fine - but jumping to the conclusion that this is a "cavalier" attitude, and then trumpeting that conclusion as fact is, IMHO, imflammatory. Your use of loaded words like "cavalier" and "frivoulous" is also likely to raise the hackles of the Apple engineers who don't like having their design decisions, which are often the result of weeks or months of work, characterized as such by someone who has little or no idea of the issues involved. >Perhaps we should subscribe to it. Object Pascal has two major >deficiencies. One is the lack of multiple inheritance; the other is >the lack of information hiding (private methods and members). Is the >ATG also looking at adding information hiding? Yes, ATG is looking at those issues as well. The basic goal is to make Object Pascal support an equivalent set of OOP features as C++, while preserving the spirit of Object Pascal. I would recommend Frameworks to anyone who is interested in OOP on the Mac. Have fun, Andrew Shebanow