rjh@cs.purdue.EDU (Bob Hathaway) (02/24/89)
In article <2325@goofy.megatest.UUCP>, djones@megatest.UUCP (Dave Jones) writes: > In an article by rjh@cs.purdue.EDU, Bob Hathaway says that he usually > uses ADT's to do top-down design and implementation... Umm, the method presented was better categorized as a modular design strategy with abstract data types. The implementation strategy was Adt/object oriented because coding began by implementing the Adts. In top-down/bottom-up terminology this corresponds to top-down design with bottom-up implementation. This strategy can be applied recursively to Adts with the top level object as the starting point in design and the bottom level sub-objects as the starting points in implementation. We know that we need an intermediate code Adt, which may require a generic tree Adt, which may require a generic list Adt, and so on. It seems natural to first identify the intermediate code Adt as necessary in the overall system design but to begin its implementation at the bottom level by using generic components. Since the following is long, I'll ask here. It would be interesting to see some discussion on design strategies; any interesting opinions or experiences? > I too have been designing all my programs around "abstract data-types" ... > But I don't usually do top-down. I do bottom-up. Design, implementation, > test, everything. It actually shocks some people when I say that. In the > seventies "bottom-up" became a dirty word. Never mind that top-down > methods resulted in some of the most inflexible code every put to disk. > Top-down good. Bottom-up bad. Unnngghh. :-) What you describe sounds like an Adt/object oriented implementation, I'm not sure if the bottom-up arguments apply. > I'll freely admit, there are times when top-down is the way to go. But > it's not the way I do most of the programs I write by myself. > > I start out with a "bottom" that consists of lots of -- okay, I'll go > along with the name -- ADT's which are likely to be of use in just > about any kind of program: lists, queues, hash-tables, avl-trees, > flexible buffers, priority queues and so on. Next I use these to form > ADT's which are specific to the low-level objects under consideration, > etc. And so it goes from bottom to top. The payoff comes when you want > to change something. All you have to do is reshuffle these building blocks, > which are still quite useful. But if you go from the top to the bottom, > a change at the top is likely to invalidate the whole blasted thing. The standard argument for top-down design is that design errors are caught early. A top level change could make all the work done at the bottom level unnecessary and major rewriting or complete scrapping could occur. That is the advantage of top-down design with bottom-up implementation, the overall design should be close to correct and the implementation is direct and fast because the objects and procedures don't depend on anything not yet implemented. I think the advantage of "building blocks" should be evident in any design since code which is designed to be easy to modify will consist of reusable and parameterized components which correspond to a loosly coupled and highly cohesive modular design. > I sometimes carry it to unlikely extremes. My group is writing a Pascal > compiler. If ever there seemed to be a top-down kind of task, that seemed to be > it. I mean, Pascal is already done, for Pete's sake. There are standards > documents which tell you what a Pascal compiler absolutely *has* to do. But.. > I started out with my bag of standard ADT's anyway, and then defined some > more: Pascal blocks, types, parms, variable-accesses... just about > every kind of Pascal-object you can think of. One by one we implemented > them as we worked our way up to type-definitions, expression-trees, statements. > The methods for these ADT's went into a library. > This sounds like a bottom-up implementation, but since the upper levels (objects) were already known in advance, a top-down design (loosly speaking). >It was only a matter of a few weeks, long before the compiler's high level >was anywhere near finished, that it paid off. Another group was doing >a mouse-driven frontend for the interactive embedded compile/load/go >feature that we have. They needed to be able to capture all of the >type-information, formal parameters and so forth about the program being >run, then fish around in it finding all the variables of this type, >building all the short expressions that are assignment compatible to the >second formal parm of procedure foo, etc.. >... > >Try doing that with a Pascal compiler that was designed top-down to >be a Pascal compiler. It sounds like the bottom-up implementation provided them with the working software early. A good design will provide reusable components which are easy to modify regardless of the implementation. Bob Hathaway rjh@purdue.edu
djones@megatest.UUCP (Dave Jones) (02/25/89)
From article <6100@medusa.cs.purdue.edu>, by rjh@cs.purdue.EDU (Bob Hathaway): > > The standard argument for top-down design is that design errors are caught > early. A top level change could make all the work done at the bottom level > unnecessary and major rewriting or complete scrapping could occur. That > is the advantage of top-down design with bottom-up implementation, the > overall design should be close to correct and the implementation is direct > and fast because the objects and procedures don't depend on anything not > yet implemented. I think the advantage of "building blocks" should be > evident in any design since code which is designed to be easy to modify > will consist of reusable and parameterized components which correspond > to a loosly coupled and highly cohesive modular design. > If you end up with "reusable and parameterized components ... loosely coupled... modular", then it doesn't matter how you got there. My argument is that in most cases, you are more likely to end up in such a software ecstacy if you use bottom-up design techniques, and you'll get there quicker. The argument for top-down design is based on some assumptions that are seldom met. If the project has these properties, top-down design can be the best order of business. 1. Design and implementation are distinct and separate activities. If they are not, you can't do one from one direction, and the other from the other direction. 2. A "correct design" can be identified without benefit of prototyping, and it will inevitably be error free. You say, "A top level change could make all the work done at the bottom level unnecessary and major rewriting or complete scrapping could occur." HATE IT when that happens! That is one reason why I design the low-level objects first. If they are designed without knowledge of the specifics of the higher levels, high level changes cannot effect them. The disaster happens when somebody "finishes" the high level design and then designs the bottom level around that, and then Ooops! -- it turns out that the high level design had a flaw in it. Then you discover that the change propogates right down through all the levels. Or maybe somebody thinks up an entirely different kind of top-end that deals with the same kinds of objects. Either way, you are likely SOL because those low level routines knew too much for their own good. Now if the design at the low level is good, all is well. Like I said, if you get there, it doesn't much matter how you got there. But which technique is less error-prone? I gave a case history of using the parts of a Pascal compiler in a mouse-clicky kind of editor. I'll reply to one comment. You said, "It sounds like the bottom-up implementation provided them with the working software early." I say, The bottom-up design provided them with software that didn't "know it was in a compiler". Recall, I did not even know about that project when I started the compiler. And I meant it literally when I said, "Try doing that with a Pascal compiler that was designed top-down to be a Pascal compiler." Actually try it. I have tried to use the parts of other production compilers to do things other than pre-runtime compilation. Not as an academic exercise, but to produce real commercial products. That's why I'm writing this one! I would rather buy the source for one off the self. Better yet, what I would really like is what I am writing: a library of low and mid level Pascal object Adt's. Then I wouldn't even need the source, except to fix bugs and port it to new platforms. But try to find such a thing: an open architecture compiler. So far as I know, I am writing the first one.
jellinghaus-robert@CS.YALE.EDU (Rob Jellinghaus) (02/27/89)
In article <2344@goofy.megatest.UUCP> djones@megatest.UUCP (Dave Jones) writes: >From article <6100@medusa.cs.purdue.edu>, by rjh@cs.purdue.EDU (Bob Hathaway): >> The standard argument for top-down design is that design errors are caught >> early. A top level change could make all the work done at the bottom level >> unnecessary and major rewriting or complete scrapping could occur. That >> is the advantage of top-down design with bottom-up implementation, the >> overall design should be close to correct and the implementation is direct >> and fast because the objects and procedures don't depend on anything not >> yet implemented. I think the advantage of "building blocks" should be >> evident in any design since code which is designed to be easy to modify >> will consist of reusable and parameterized components which correspond >> to a loosly coupled and highly cohesive modular design. > >If you end up with "reusable and parameterized components ... loosely >coupled... modular", then it doesn't matter how you got there. >My argument is that in most cases, you are more likely to end up >in such a software ecstacy if you use bottom-up design techniques, >and you'll get there quicker. Everyone involved in this discussion should get their hands on a copy of Bertrand Meyer's book _Object-Oriented Software Construction_, Prentice- Hall, 1988. The design philosophy being discussed sounds virtually identical to Meyer's exposition of the object-oriented design method. Briefly, Meyer's summary of object-oriented design is as follows: Ask not what the system does, ask what it does it to. In other words, the most important characteristic of the system is NOT its overall "intended function". The most important description of the system is in terms of the objects, the data, that is manipulated by the system. This is more akin to bottom-up design than to top-down design, for sure, although the emphasis is slightly different. >You say, "A top level change could make all the work done at the bottom level >unnecessary and major rewriting or complete scrapping could occur." > >HATE IT when that happens! > >That is one reason why I design the low-level objects first. If they are >designed without knowledge of the specifics of the higher levels, high >level changes cannot effect them. The disaster happens when somebody >"finishes" the high level design and then designs the bottom level around >that, and then Ooops! -- it turns out that the high level design had a flaw >in it. Then you discover that the change propogates right down through >all the levels. The typical top-down design spec is functionally oriented; i.e. "We want the system to Do This, and in order to Do It, it'll have to do this, and this, and this..." etc., etc. When you change your mind about what you want it to Do, you're hosed. Object-oriented style avoids this, by focusing the design effort on the structure of the data to be handled, rather than on the design of the whole system. A proper object-oriented design is inherently modular, and seldom needs a complete revision; the modules are organized in a network rather than in a hierarchical tree, which means changes to the net can be made without affecting the whole system; whereas if you need to change the root of a top-down tree, you're hosed. >I gave a case history of using the parts of a Pascal compiler in >a mouse-clicky kind of editor. I'll reply to one comment. >You said, "It sounds like the bottom-up implementation provided them >with the working software early." > >I say, The bottom-up design provided them with software that didn't >"know it was in a compiler". Recall, I did not even know about that >project when I started the compiler. Exactly. Your objects were general enough to be free from a specific system. This is reusability, and Meyer talks about how to get it. A lot. >I have tried to use the parts of other production compilers >to do things other than pre-runtime compilation. Not as an academic >exercise, but to produce real commercial products. That's why I'm >writing this one! I would rather buy the source for one off the self. >Better yet, what I would really like is what I am writing: a library of >low and mid level Pascal object Adt's. Then I wouldn't even need the >source, except to fix bugs and port it to new platforms. But try to >find such a thing: an open architecture compiler. So far as I know, I >am writing the first one. You should definitely go out and take a look at this book. One of Eiffel's (Meyer's language) main selling points is its reusable object library, with everything from arrays to hash tables to an Xwindows library already coded. (According to reports, lexical analysis and (someday) concurrency libraries will be available too.) Sounds right up your alley! Rob Jellinghaus | "Next time you see a lie being spread or a jellinghaus-robert@CS.Yale.EDU | bad decision being made out of sheer ignor- ROBERTJ@{yalecs,yalevm}.BITNET | ance, pause, and think of hypertext." {everyone}!decvax!yale!robertj | -- K. Eric Drexler, _Engines of Creation_
billwolf@hubcap.clemson.edu (William Thomas Wolfe,2847,) (02/27/89)
From article <51955@yale-celray.yale.UUCP>, by jellinghaus-robert@CS.YALE.EDU (Rob Jellinghaus): > Everyone involved in this discussion should get their hands on a copy > of Bertrand Meyer's book _Object-Oriented Software Construction_, Prentice- > Hall, 1988. The design philosophy being discussed sounds virtually > identical to Meyer's exposition of the object-oriented design method. I'd suggest Booch's coverage of object-oriented design in "Software Components with Ada" instead; Meyer's book comes bound up with a rather flaky programming language. > You should definitely go out and take a look at this book. One of Eiffel's > (Meyer's language) main selling points is its reusable object library, > with everything from arrays to hash tables to an Xwindows library already > coded. (According to reports, lexical analysis and (someday) concurrency > libraries will be available too.) Ada has far more reuseable ADTs already coded. I'm coding a concurrent ADT right now, in fact. Vendors such as EVB, lib systems, Wizard Software, and so on, have entire catalogs of Ada components you can buy right off the shelf, and Ada's rigorous standardization ensures that they'll compile anywhere. Booch's other book, "Software Engineering with Ada" is also worth reading, and I think it also contains something on object-oriented design. ("Software Components" is more of an advanced text) Also, one can obtain a magtape copy of the Ada Software Repository from MACA Attn: Janet Mckellar P.O. Drawer 100 - Bldg T148 White Sands Missile Rang, NM 88002 It fills up an entire magtape at 6250 bpi in tar format, and costs essentially nothing; all they need is your magtape and enough postage to get it back to you. The Ada Information Clearinghouse Newsletter periodically summarizes major Ada software libraries and systems; it's free, and you can get on the mailing list by sending a postcard to Ada Information Clearinghouse c/o IIT Research Institute 4600 Forbes Blvd., Second Floor Lanham, MD 20706-4312 Also, the recent issue of ACM SIGADA Ada Letters contains several interesting articles on ADT design and object-oriented programming. Bill Wolfe, wtwolfe@hubcap.clemson.edu comp.sw.components Mailing List administrator
sommar@enea.se (Erland Sommarskog) (02/27/89)
Bill Wolfe (wtwolfe@hubcap.clemson.edu) writes: Rob Jellinghaus (jellinghaus-robert@CS.YALE.EDU) said: >> Everyone involved in this discussion should get their hands on a copy >> of Bertrand Meyer's book _Object-Oriented Software Construction_, Prentice- >> Hall, 1988. The design philosophy being discussed sounds virtually >> identical to Meyer's exposition of the object-oriented design method. > > I'd suggest Booch's coverage of object-oriented design in > "Software Components with Ada" instead; Meyer's book comes > bound up with a rather flaky programming language. I don't want to start an Ada vs. Eiffel debate, but the view that Eiffel is a flaky language is something Bill Wolfe have to stand for himself. What I like to stress is: Ada is *not* an object-oriented language. I used to think that, but there are just to much missing. Particulary inheritance and dynamic typing. And although this is a trivial fact to realise, it still seems necessary that from time to time make a reminder about this. Due to Gary Booch and others it is easy for the casual reader to get the impression that Ada <=> object-oriented programming. But it's true that Ada is better for applying object-oriented strategies than most other "conventional" languages. As for bottom-up vs. top-down, Meyer explains this very well in his book, and it's certainly applicable to the recent discussion. One drawback with top-down I haven't seen well covered, is the big risk that you never see that two leaves are the same, or see it too late, so you get the same code in two places. (Or even worse, you should have two identical pieces of code, but in fact they are different.) The project I'm in right now was designed top-down, if it was designed at all. (It's a real mess, but don't blame me I came in too late.) And it is a clear mistake. OK, there is a set of library routines for low-level objects like formatting routines and simple database accesses. But very little for handling of high-order objects like account statements and other application specific things. I have tried to introduce it, but when you need more than a day for it, you get in conflict with the time schedule, whichh of course give no place for "luxury" like that. -- Erland Sommarskog ENEA Data, Stockholm This signature is not to be quoted. sommar@enea.se
jwb@cive.ri.cmu.edu (John Baugh) (02/27/89)
In article <4571@hubcap.UUCP> wtwolfe@hubcap.clemson.edu writes: >From article <51955@yale-celray.yale.UUCP>, by > jellinghaus-robert@CS.YALE.EDU (Rob Jellinghaus): >> Everyone involved in this discussion should get their hands on a copy >> of Bertrand Meyer's book _Object-Oriented Software Construction_, ... >> [discussion of decomposition methods deleted] > I'd suggest Booch's coverage of object-oriented design in > "Software Components with Ada" instead; ... IMHO, these ideas were more clearly expressed by people like Parnas and Liskov back in the 70's. For instance: D. Parnas, "On the criteria to be used in decomposing systems into modules," CACM, v15, Dec. 1972. and more recently: B. Liskov and J. Guttag, _Abstraction_and_Specification_in_Program_ _Development_, MIT Press and McGraw Hill, 1986. Of course, the phrases "information hiding" and "ADT" don't sound as high-tech as "object-oriented" :-) (Comments about polymorphism and inheritance unnecessary, and flames to /dev/null.). John Baugh --
billwolf@hubcap.clemson.edu (William Thomas Wolfe,2847,) (02/27/89)
From article <4343@enea.se>, by sommar@enea.se (Erland Sommarskog): > I don't want to start an Ada vs. Eiffel debate, but the view that > Eiffel is a flaky language is something Bill Wolfe have to stand for > himself. > > What I like to stress is: Ada is *not* an object-oriented language. > I used to think that, but there are just to much missing. Particulary > inheritance and dynamic typing. And although this is a trivial fact to > realise, it still seems necessary that from time to time make a reminder > about this. Due to Gary Booch and others it is easy for the casual > reader to get the impression that Ada <=> object-oriented programming. I quote from ACM SIGADA Ada Letters, March/April 1989, Volume IX, Number 2, Page 10: Software Productivity Solutions, Inc., has announced a new product, Classic-Ada (tm), which allows Ada software developers to use inheritance and dynamic binding in object-oriented Ada designs. The product runs on VAX/VMS and Sun/Unix systems. For more information, contact: (407) 984-3370 Ms. Lois Valley Vice President, Marketing Software Productivity Solutions, Inc. P.O. Box 361697 Melbourne, FL 32936-1697 I stand by my statement regarding Eiffel's flakiness. Obviously it's just my opinion, and others may differ, but I think it's a very well-founded opinion. Bill Wolfe, wtwolfe@hubcap.clemson.edu
mike@arizona.edu (Mike Coffin) (02/28/89)
From article <4574@hubcap.UUCP> (William Thomas Wolfe,2847,):
> I stand by my statement regarding Eiffel's flakiness.
Do you mean that the language design is flakey, or that an
implementation is flakey? If the former, what is flakey about it?
--
Mike Coffin mike@arizona.edu
Univ. of Ariz. Dept. of Comp. Sci. {allegra,cmcl2}!arizona!mike
Tucson, AZ 85721 (602)621-2858
rjh@cs.purdue.EDU (Bob Hathaway) (02/28/89)
In article <2344@goofy.megatest.UUCP>, djones@megatest.UUCP (Dave Jones) writes: >If you end up with "reusable and parameterized components ... loosely >coupled... modular", then it doesn't matter how you got there. >My argument is that in most cases, you are more likely to end up >in such a software ecstacy if you use bottom-up design techniques, >and you'll get there quicker. We agree the components are desirable but a modular design should get you there quickly too. By breaking the system into smaller pieces with each piece providing some well defined and more manageable part of the system, the components should emerge. Not only for the objects, but for the software tools as well. >I have tried to use the parts of other production compilers >to do things other than pre-runtime compilation. Not as an academic >exercise, but to produce real commercial products. That's why I'm Yes I have too. I've taken a parser out of a 100,000 line compiler and it wasn't pleasant. I couldn't just take out the parser because it was inextricable tied to the scanner and some semantics (typechecking) was performed there too. This undoubtable was due to efficiency reasons and not top-down design. If on the other hand the design had taken reusable software tools into account the parser, scanner, and type system would be separate entities with each providing a well defined interface. It would be infeasible to reuse or add another scanner and much effort went into taking the pieces out to the point where they were reusable. They finally did provide reusable components, the parser (and type-system) generated an idl file representing the parsed functions and was used immediately by two applications. Someone recently asked to use the parser/type-system and since yyparse (the parser) was modified to return an object representing all the parsed declarations before passing them to idl routines for output, he had exactly what he wanted in no time. With just a little foresight on the part of the compiler designers and with a greater priority given to software reuse the front-end of the compiler would have provided the "software ecstasy" sought. Of course, Adts would have added greater potential for reuse of the data structures involved but the tools were important too. >The argument for top-down design is based on some assumptions that are >seldom met. If the project has these properties, top-down design >can be the best order of business. > > 1. Design and implementation are distinct and separate activities. > > If they are not, you can't do one from one direction, and the > other from the other direction. For projects which are not large, I think design will correspond to recognizing the objects and major software components of the system, and probably informal coding. This isn't a major effort and can force recognizing all issues involved very early. For large projects, design and implementation should be separate. > 2. A "correct design" can be identified without benefit of prototyping, > and it will inevitably be error free. Aren't prototypes usually top-down and provide a skeletal framework to show users so they can decide if the software is what they want, with each function possibly stubbed out to provide simple or no service? Or maybe just a fast implementation to show the bottom level is even possible, but I don't see what prototypability has to do with top-down design, to verify the designs correctness? I think prototyping can show the validity of a "correct design", in other words top-down design with the benefit of prototyping. >Or maybe somebody thinks up an entirely different kind of top-end that >deals with the same kinds of objects. Either way, you are likely SOL >because those low level routines knew too much for their own good. Now >if the design at the low level is good, all is well. Like I said, if you >get there, it doesn't much matter how you got there. But which technique >is less error-prone? Good design will keep the low-level routines from knowing too much, top-down or otherwise. Just keep this in mind and you're SIL:-) >I say, The bottom-up design provided them with software that didn't >"know it was in a compiler". Recall, I did not even know about that >project when I started the compiler. >And I meant it literally when I said, "Try doing that with a Pascal >compiler that was designed top-down to be a Pascal compiler." > >Actually try it. > But with a modular design (top-down within modules) the tools are functionally separate and they should not know they are a compiler, just what their well defined function is to provide and an interface to meet. I think keeping separate functionality separate is something thats really important regardless of whether the encapsulation comes through packages, processes, or whatever. The same applies to objects, even when designed top-down the lower level implementation of the Adt should be based on components which are as generic as possible, I don't see how providing the implementation calls for non-generic units since the recursive application of good design will call for modular and generic components which are used to implement the object. I can see that if a designer throws away all design principles after identifying the top level object he could end up with an unstructured, data-structure oriented, special purpose implementation but that should be easy to avoid. Bob Hathaway rjh@purdue.edu
rjh@cs.purdue.EDU (Bob Hathaway) (02/28/89)
In article <4343@enea.se>, sommar@enea.se (Erland Sommarskog) writes: >But it's true that Ada is better for applying object-oriented strategies >than most other "conventional" languages. I strongly agree, most other conventional languages are data-structure oriented and not Adt/object oriented in programming constructs or methodology. >As for bottom-up vs. top-down, Meyer explains this very well in his >book, and it's certainly applicable to the recent discussion. Could you elaborate on this, does he advocate top-down, bottom-up, ??? I haven't read Meyer's book. Bob Hathaway rjh@purdue.edu
sdl@linus.UUCP (Steven D. Litvintchouk) (02/28/89)
In article <4574@hubcap.UUCP> billwolf@hubcap.clemson.edu (William Thomas Wolfe,2847,) writes: > From article <4343@enea.se>, by sommar@enea.se (Erland Sommarskog): > > What I like to stress is: Ada is *not* an object-oriented language. > > [it lacks] inheritance and dynamic typing..... > > Software Productivity Solutions, Inc., has announced a new product, > Classic-Ada (tm), which allows Ada software developers to use > inheritance and dynamic binding in object-oriented Ada designs. Lest anyone get the wrong impression about Classic-Ada, let me clarify: The Classic-Ada language is *not* legal Ada. It is a unique dialect, which consists of Ada extended (nicely) with a new construct--the class--with inheritance and dynamic binding. SPS, Inc., is to be commended for attempting to improve Ada's support for object oriented programming. But the resulting Classic-Ada language is not legal Ada. Classic-Ada programs must be put thru SPS' translator to generate legal Ada. Mr. Sommarskog is quite correct. Ada lacks any specific mechanism for defining relationships among classes; the Classic-Ada language provides just this mechanism. Eiffel does manage to provide inheritance in a reasonably strongly-typed framework. In their zeal to facilitate object-oriented programming, SPS added both inheritance and dynamic binding to Classic-Ada. Was dynamic binding necessary? It seems to entirely defeat the safety and reliability that was a goal of Ada. I believe that Eiffel tries to provide both separate compilation and generics, just like Ada. And, just like Ada, I would suspect that the early Eiffel compilers will have "teething problems." (At OOPSLA '88, I recall that several Eiffel users reported problems with the Eiffel library manager; a real case of deja vu for us veteran Ada programmers.) Steven Litvintchouk MITRE Corporation Burlington Road Bedford, MA 01730 Fone: (617)271-7753 ARPA: sdl@mitre-bedford.arpa UUCP: ...{att,decvax,genrad,ll-xn,philabs,utzoo}!linus!sdl "Those who will be able to conquer software will be able to conquer the world." -- Tadahiro Sekimoto, president, NEC Corp.
sdl@linus.UUCP (Steven D. Litvintchouk) (02/28/89)
In article <9443@megaron.arizona.edu> mike@arizona.edu (Mike Coffin) writes: > From article <4574@hubcap.UUCP> (William Thomas Wolfe,2847,): > > I stand by my statement regarding Eiffel's flakiness. > > Do you mean that the language design is flakey, or that an > implementation is flakey? If the former, what is flakey about it? From what I was able to gather at OOPSLA '88, the current Eiffel *implementations* are indeed flaky, but no more so than was any Ada compiler developed prior to 1985. I am extremely interested in finding out whether Eiffel compilers do a better job compiling Eiffel generics, than Ada compilers do compiling Ada generics. I remain disappointed in how poorly Ada generics are implemented by some Ada compilers. Steven Litvintchouk MITRE Corporation Burlington Road Bedford, MA 01730 Fone: (617)271-7753 ARPA: sdl@mitre-bedford.arpa UUCP: ...{att,decvax,genrad,ll-xn,philabs,utzoo}!linus!sdl "Those who will be able to conquer software will be able to conquer the world." -- Tadahiro Sekimoto, president, NEC Corp.
jellinghaus-robert@CS.YALE.EDU (Rob Jellinghaus) (02/28/89)
In article <6127@medusa.cs.purdue.edu> rjh@cs.purdue.EDU (Bob Hathaway) writes: >In article <4343@enea.se>, sommar@enea.se (Erland Sommarskog) writes: >>As for bottom-up vs. top-down, Meyer explains this very well in his >>book, and it's certainly applicable to the recent discussion. > >Could you elaborate on this, does he advocate top-down, bottom-up, ??? >I haven't read Meyer's book. Meyer advocates neither, although his strategy (which he terms simply "object-oriented design") is closer to bottom-up than to top-down. His claim is that the best way to obtain reusability, maintainability, and reliability (which should all result from good software engineering technique), the best method is to focus design on the data objects that the program is manipulating. The resulting design can often be very obvious, as it isn't too hard to find the objects in most applications. Object-oriented languages then package the objects and their internal representation together with the routines that operate on them, and thus separate interface from implementation. A good object-oriented system quite often will consist largely of software components that have been taken from older projects, which is not really a possibility in either the top-down or the bottom-up model. If the map of a top- down system is a tree, with the principal function at the top, then an object-oriented system is a net, with each object providing services to other objects, with no clear hierarchical arrangement; this enables the system to be locally modified without global effects. That's a very brief summary of Meyer's arguments. He goes into more detail, with examples, in the book. To respond briefly to Bill Wolfe's comments about Eiffel being flaky: I can't say how good a language Eiffel is in the real world. However, Meyer uses it very effectively as an exemplar of a good object-oriented programming language, and at every step throughout the book he discusses the design decisions he made in creating Eiffel, and what the impli- cations are for object-oriented programs. He discusses the pros and cons of Ada, Smalltalk, etc., etc. at length, and he talks about the essential features of any "true" (in his definition) object-oriented language: multiple inheritance, genericity, polymorphism, dynamic binding, etc. Even if you don't agree with his decisions, his exposition is very clear and (in my opinion) well-written. (You can probably tell I like the book!) >Bob Hathaway >rjh@purdue.edu Rob Jellinghaus | "Next time you see a lie being spread or a jellinghaus-robert@CS.Yale.EDU | bad decision being made out of sheer ignor- ROBERTJ@{yalecs,yalevm}.BITNET | ance, pause, and think of hypertext." {everyone}!decvax!yale!robertj | -- K. Eric Drexler, _Engines of Creation_
mikael@sm.luth.se (Mikael Eriksson) (02/28/89)
In article <4574@hubcap.UUCP> wtwolfe@hubcap.clemson.edu writes: >From article <4343@enea.se>, by sommar@enea.se (Erland Sommarskog): >> What I like to stress is: Ada is *not* an object-oriented language. > > I quote from ACM SIGADA Ada Letters, March/April 1989, Volume IX, > Number 2, Page 10: > > Software Productivity Solutions, Inc., has announced a new product, > Classic-Ada (tm), which allows Ada software developers to use > inheritance and dynamic binding in object-oriented Ada designs. You mean that they sell a *super-set* of ADA? Mild sarcasm on: This must be what we all have been waiting for ! Mild sarcasm off. ADA is too much of an elephant already. I totally agree that inheritance is good but ADA would have to be pruned a lot before something new should be added to it. mikael -- Mikael Eriksson (Email: mikael@sm.luth.se) ......... You are in error. 2+2=5 Thank you for your cooperation. The Computer.
prc@maxim.ERBE.SE (Robert Claeson) (02/28/89)
Bill, In article <4574@hubcap.UUCP>, you write: > I stand by my statement regarding Eiffel's flakiness. Obviously > it's just my opinion, and others may differ, but I think it's a > very well-founded opinion. Can you please elaborate on that? I'm sure there are quite a few people around who wants to know in what ways Eiffel is flaky. -- Robert Claeson, ERBE DATA AB, P.O. Box 77, S-175 22 Jarfalla, Sweden Tel: +46 (0)758-202 50 Fax: +46 (0)758-197 20 EUnet: rclaeson@ERBE.SE uucp: {uunet,enea}!erbe.se!rclaeson ARPAnet: rclaeson%ERBE.SE@uunet.UU.NET BITNET: rclaeson@ERBE.SE
djones@megatest.UUCP (Dave Jones) (03/01/89)
From article <6126@medusa.cs.purdue.edu>, by rjh@cs.purdue.EDU (Bob Hathaway): > > We agree the components are desirable but a modular design should get you > there quickly too. > I'm not willing to give over the term "modular design" to the piecewise refinement school. I design modules (or "classes", or "Atds", or "components" or whatever). Sometimes, but seldom, I actually do use piecewise refinement as an design or implementation technique. The modules are the "what". The piecewise refinement is the "how". If you get good modules from piecewise refinement, good for you! I've seldom seen anybody else pull it off, but that's no reason to presume that it doesn't work for you. My assertion -- must I repeat it again? -- is that good modules are more likely to come from a bottom-up approach. Designing the top levels first is just too darn risky for my tastes. > By breaking the system into smaller pieces with each > piece providing some well defined and more manageable part of the system, > the components should emerge. > Components might emerge. But how they emerge may be dictated by the top level. That's what I don't want. The top level might have to change. Why not just begin by designing components? That way, they don't have to "emerge". They are part and parcel of the design itself. > Not only for the objects, but for the software tools as well. I've never seen it happen that way, but then I've only been doing this stuff for eighteen years. Maybe next week. :-) ... I'm going to get out of the discussion for a while. I've been spending too much time on this as it is. Let me just say one thing: I've known some people -- and be assured that I do not intend to suggest that Mr. Hathaway is in this camp -- who have preached piecewise refinement as a dogma for so long that it would take something akin to a religious conversion to get them even to consider other techniques. I am trying to point that it just that: a technique. The product is the thing. We are sometimes free to choose the best methods on a product-by-product basis. Which method is best depends on the job at hand. Top-down design and piecewise refinement is, in my opinion, seldom the best technique to use.
djones@megatest.UUCP (Dave Jones) (03/01/89)
From article <52101@yale-celray.yale.UUCP>, by jellinghaus-robert@CS.YALE.EDU (Rob Jellinghaus): > A good object-oriented > system quite often will consist largely of software components that > have been taken from older projects, which is not really a possibility > in either the top-down or the bottom-up model. If the map of a top- > down system is a tree, with the principal function at the top, then > an object-oriented system is a net, with each object providing > services to other objects, with no clear hierarchical arrangement; > this enables the system to be locally modified without global effects. > Point of semantics well taken. Perhaps I should not be using the term "bottom-up". I guess if you get into the topology of it, inheritance of structure (not reference), yields a directed acyclic graph which may have lots of local bottoms and tops. But if I said, "infrenum-supremum" programming, who would know what I was talking about? Dave J.
rjh@cs.purdue.EDU (Bob Hathaway) (03/03/89)
In article <2542@goofy.megatest.UUCP>, djones@megatest.UUCP (Dave Jones) writes: >...My assertion -- must I repeat it again? -- >is that good modules are more likely to come from a bottom-up approach. Ok, I'll admit you've made a good point although I still think starting at the top is the natural way to design systems (and algorithms). >> By breaking the system into smaller pieces with each >> piece providing some well defined and more manageable part of the system, >> the components should emerge. >> >Components might emerge. But how they emerge may be dictated by the >... Ok, how about a quick example starting at top level. When designing a "Classical" compiler/interpreter front-end, I know the structure will consist of a scanner to read input and a parser to read the grammar. I'll assume the parser functions return an intermediate code Adt for triviality. Now, I know I'll need a symbol table for identifiers and reserved words and a token type to return to the parser, and we have: |-------| |------| |------------| |scanner|------>|parser|---->|intermediate| |-------| |------| | code | \ / |------------| \ / |-------| |symbol | |table | |-------| Their are four top-level modules immediately identified. 1. Symbol Table Provides a symbol_table_entry Adt (encapsulates a type). <Description> Operations a. lookup/insert <Description> ... 2. Scanner Provides TokenType Adt (encapsulates a type). <Description> Operations a. Next_Token <Description> b. Match_Token <Description> ... 3. Intermediate Code Provides Intermediate_Code Adt (encapsulates a type) <Description> Operations a. Make_Node <Description> b. Make_Child <Description> ... 4. Parser Parses input (encapsulates functionally related subprograms). <Description> Operations a. Statement Returns an intermediate code representation of the parsed statement... b. Parse Go for the whole thing:-) ... Thus, a modular design with Adts. The design can proceed by identifying the return values and parameters to operations and possibly some high level pseudo code to insure the problem is well understood and all parts of the system will work together as expected. To begin the implementation we analyze the dependencies, almost always the Adts come last. Dependencies parser: scanner, symbol table, intermediate code, scanner: symbol table symbol table: nothing intermediate code: nothing We can begin implementation with the intermediate code and symbol table because we know what they need to provide and how they fit into the system and because they don't depend on unwritten code. Yes, the token, symbol table, and intermediate code Adts won't change much and are good candidates for reuse; I wouldn't expect to add more than one or two operations and change more than a few parameters for each Adt above after the initial design is complete. Each module provides a well defined interface and encapsulates either a type (Adt) or a set of functionally related subprograms (the parser). After the top level design is complete we can turn to the internal design of the Adts. For example the intermediate code Adt may be complex requiring recursive application of the above technique, i.e. top down. So, a generic tree Adt from a library can be used, and so on, nothing special purpose. The parser functions can be designed top-down and implemented bottom-up, so we'll know what gramatical constructs are necessary from the top and get there fastest from the bottom (the preferred implementation technique for parsers). Efficiency considerations can come later *if* the system doesn't meet its timing constraints, good design comes first. We wouldn't know where to optimize until profiling anyway. Classification: Object Oriented (design & implementation) Yes: objects identified, 2nd level design and coding begins with objects (data structures). No : no inheritance. Top-Down (design) Yes: Top-down design is used within modules, especially in the parser. No : Structure charts were possible, but modules provided the best high level view of the system. Bottom-up (implementation) Yes: started with the lowest level Adt. Generic linked lists, tree adts, etc., would be used to implement the Adts from the bottom up. What I call this mess: Modular design with abstract data types, top-down design within modules. Reuse: All software tools and components are conceivably replaceable and reusable. >... Which method is best depends on the job at hand. ... I agree, the above technique was chosen after carefully considering the problem and I have found it suitable for most, if not all applications. Direct encoding of the design and implementation is possible in Ada and to my understanding this is the preferred application of Ada's methodology. Flamage and comments are welcome. In view of the recent object-oriented discussions, can anyone comment on how inheritance, dynamic binding, or any other object oriented techniques fit into or could improve the above scheme? I'll be disappointed if the modular technique with Adts is the only one provided:-) Bob Hathaway rjh@purdue.edu
agnew@trwrc.UUCP (Robert A. Agnew) (03/04/89)
In article <45491@linus.UUCP> sdl@linus.UUCP (Steven D. Litvintchouk) writes: >In article <4574@hubcap.UUCP> billwolf@hubcap.clemson.edu (William Thomas Wolfe,2847,) writes: > >> From article <4343@enea.se>, by sommar@enea.se (Erland Sommarskog): >> Software Productivity Solutions, Inc., has announced a new product, >> Classic-Ada (tm), which allows Ada software developers to use >> inheritance and dynamic binding in object-oriented Ada designs. I believe there is also a proposal for the 199x revision to Ada to introduce Package types. The package type is the analogy of the C++ class. As far as I know there has been no proposal to include constructor and destrustor operators, but this certainly should be considered.
snidely@inteloa.intel.com (David P. Schneider) (03/09/89)
Another point to note is that for large (complex) projects, identifying the subject of ADTs (e.g., Object-oriented design) may require an analysis step using traditional requirements-oriented techniques, such as data-flow di- agrams. The associated data dictionary would then be used to identify the objects or components, and the transform bubbles would be used to identify the required operations on those objects. Note that traditional software engineering (Pressman, for instance) breaks the pre-release part of a project into *three* phases: analysis first, then design, and finally implementation. Analysis tries to identify system characteristics and requirements without going into design- or implementation-level descriptions (which would prematurely constrain op- tions); design translates the output of analysis into implementable specif- ications, and implementation puts code behind them thar words. Note that the differentiation is a matter of degree more than type. I'm gearing up for a term paper on the subject of object-oriented design and software reuse in complex projects, and if you can provide me with some additional references in the trade journals, or have had experience with using ADT/object-oriented design on large projects, your mail would be wel- come. David P. Schneider BiiN (tm) Wednesday, 3.8
shf@well.UUCP (Stuart H. Ferguson) (03/11/89)
+-- rjh@cs.purdue.EDU (Bob Hathaway) writes: | In article <>, djones@megatest.UUCP (Dave Jones) writes: | >...My assertion -- must I repeat it again? -- | >is that good modules are more likely to come from a bottom-up approach. | Ok, I'll admit you've made a good point although I still think starting at | the top is the natural way to design systems (and algorithms). [ ... ] | Ok, how about a quick example starting at top level. When designing | a "Classical" compiler/interpreter front-end, I know the structure will | consist of a scanner to read input and a parser to read the grammar. [ ... ] Bob goes on to develop a design for a compiler front end in a very rational and structured top-down type way. The problem with this example is that it already a solved problem. Parsing computer languages is such a well solved problem in fact that there are tools to generate these programs automatically from terse formal descriptions. The real test of a design methodology is to try it on a not-so-well solved problem. How would you go about designing a WYSIWYG text processing program, or a hyper-text environment, or a graphical user interface toolkit? (If you've done these before, substitute something you have no IDEA about how to design.) The pure "top-down" approach starts with some black box called "the system" which you then break into smaller units and those into even smaller units until you have something you can implement in a page or two of code. The difficulty is that the first decision you have to make (i.e. breaking "the system" into a first level of components) is the most far-reaching and nearly impossible to make without knowing the whole design first. Also, you know that users are going to demand things you can't imagine now, so how do you go about designing your systems now so they are expandable enough to meet the needs of the future? Reference: David Parnas, Paul Clements "A Rational Design Process: How and Why to Fake It." IEEE trans soft-eng Feb 1986 The first part of the article is priceless. -- Stuart Ferguson (shf@well.UUCP) Action by HAVOC
janssen@titan.sw.mcc.com (Bill Janssen) (03/20/89)
Modula-3 and Turing both seem to be nice languages. But I feel that we are past the point where a language that has all the "good" SE features can really be small and easy to learn. We just know more about what helps to build good code. What we need is a language that can be learned (and used) in steps, as a person learns the methodological steps that drive each part of the language. Bill