billwolf%hazel.cs.clemson.edu@hubcap.clemson.edu (William Thomas Wolfe, 2847 ) (09/05/89)
On the subject of why reuse does not take place more frequently, the article appearing just before the one Scott cited ("Can Programmers Reuse Software?" IEEE Software, July '87, pp. 52-60) comments: If the worth of reusing an ADT could be accurately assessed, we would expect a person to reuse an ADT even if only a few percent of the creation effort could be saved... Software development personnel untrained in software reuse are influenced by some unimportant features [of a component] and are not influenced by some important ones... users cannot properly assess the worth of reusing a candidate ADT... Also, regarding the hardware analogy, it does not draw a direct correspondence between computer software and computer hardware; rather, it draws an analogy to the extensive catalogs of ICs, resistors, capacitors, etc. used by electrical engineers to build all kinds of application-specific products. It seeks to diminish the "art form" mindset, replacing it with "engineering discipline". Bill Wolfe, wtwolfe@hubcap.clemson.edu
scotth@boulder.Colorado.EDU (Scott Henninger) (09/05/89)
|>From: billwolf%hazel.cs.clemson.edu@hubcap.clemson.edu (William Thomas Wolfe, 2847 ) |Subject: Re: Reasons for low reuse |Date: 5 Sep 89 01:21:47 GMT | | ("Can Programmers Reuse Software?" IEEE Software, July '87, pp. 52-60) So we must ask ourslves - Do we want to "train" people to become successful reusers, or should we provide adequate support for reusing software. It is not clear to me that all of the training in the world will solve the problem. The problem is twofold (maybe more): First of all, there are potentially millions of components to choose from. No one could possibly keep track of all of them. Support for retrieving useful components is therefore needed. Secondly, once you've got a component, you must tailor it to your specific needs. This means understanding the code or some description of the code. Anyone who has debugged code written by others can attest to just how difficult this is. The "conceptual closeness" measures devised by Prieto-Diaz are a first step in trying to assess the modifiability of a component. One could also argue that conceptual level (as opposed to implementation level) descriptions are needed (no, current documentation techniques are not sufficient). | Also, regarding the hardware analogy, it does not draw a direct | correspondence between computer software and computer hardware; | rather, it draws an analogy to the extensive catalogs of ICs, | resistors, capacitors, etc. used by electrical engineers to build | all kinds of application-specific products. Again, this assumes that the components can be used without modification. This is not the norm with software, but is with hardware. Also, we must keep in mind that resistors and capacitors implement one kind of machine. For software, we must find the equivalents of resistors and capacitors for each domain we write software for. | It seeks to diminish the "art form" mindset, replacing it with "engineering | discipline". To claim that this is true is to claim that all the world's domains can be reduced to engineering principles. While it's a worthy goal, I'm not so sure that it can be done. I would like to hear other opinions. Anyone out there? -- Scott scotth@boulder.colorado.edu
uucibg@swbatl.UUCP (3929) (09/06/89)
In article <11347@boulder.Colorado.EDU> scotth@boulder.Colorado.EDU (Scott Henninger) writes: >| Also, regarding the hardware analogy, it does not draw a direct >| correspondence between computer software and computer hardware; >| rather, it draws an analogy to the extensive catalogs of ICs, >| resistors, capacitors, etc. used by electrical engineers to build >| all kinds of application-specific products. > >Again, this assumes that the components can be used without modification. This >is not the norm with software, but is with hardware. Also, we must keep in mind >that resistors and capacitors implement one kind of machine. For software, we >must find the equivalents of resistors and capacitors for each domain we write >software for. > >| It seeks to diminish the "art form" mindset, replacing it with "engineering >| discipline". > >To claim that this is true is to claim that all the world's domains can be >reduced to engineering principles. While it's a worthy goal, I'm not so sure >that it can be done. > >I would like to hear other opinions. Anyone out there? >-- Scott > scotth@boulder.colorado.edu I think I'm probably jumping in way over my head here, but I'll hazard a very naive opinion... :-). It would seem to me that the hardware analogy is actually rather appropriate. But before anyone goes and rants all over me, think about how many engineers we have out there. Obviously, "engineering" is still an art too. Namely, it is the art of examinging a body of solutions to previous problems and trying to find one or more solutions which can be adapted to solve the current problem. I don't see any way to claim that this isn't still an art, since we would have replaced all those engineers with computers if it weren't an art. This makes me believe that there will always be a certain art to software development. I would never claim that engineers are not in some sense of the word artists. In this respect, software component development seems to have two major fronts: 1) coming up with better techniques for identifying commonality between problems (and therefore their solutions). This is perhaps as much a "way of thinking" task as it is an infrastructure development task. Not to say that there isn't a *lot* of infrastructure that we can develop. Quite the contrary, I would agree with previous statments that software component technologies are rather embryonic (lots of room for fortunes to be made.... :-). 2) Convince the world (through case studies) that reuse can save them time and dollars. This is the only thing that will convince the "suits" that this wonderful infrastructure is worth paying for and worth the cost of retraining their people to use. If this is all very obvious to everyone, sorry... Thanks, -------------------------------------------------------------------------------- Brian R. Gilstrap ...!{ {killer,bellcore}!texbell, uunet }!swbatl!uucibg One Bell Center +---------------------------------------------------------- Rm 17-G-4 | "Winnie-the-Pooh read the two notices very carefully, St. Louis, MO 63101 | first from left to right, and afterwards, in case he had (314) 235-3929 | missed some of it, from right to left." -- A. A. Milne -------------------------------------------------------------------------------- Disclaimer: Me, speak for my company? You must be joking. I'm just speaking my mind.
billwolf%hazel.cs.clemson.edu@hubcap.clemson.edu (William Thomas Wolfe, 2847 ) (09/06/89)
From scotth@boulder.Colorado.EDU (Scott Henninger): > | ("Can Programmers Reuse Software?" IEEE Software, July '87, pp. 52-60) > > [...] It is not clear to me that all of the training in the world will > solve the problem. The problem is twofold (maybe more): First of all, > there are potentially millions of components to choose from. [...] The first problem that has to be overcome is the Not Invented Here syndrome; we must have programmers who want to use components. This can be addressed by training (at the university level), and also by appeal to management (in the "real world"). Incidentally, the hardware analogy is absolutely wonderful for convincing non-technical managers of the value of reuse; they grasp it instantly, and immediately become enthusiastic supporters. > Secondly, once you've got a component, you must tailor it to your > specific needs. This means understanding the code or some description > of the code. Anyone who has debugged code written by others can attest > to just how difficult this is. Wonderful reasons for NOT DOING IT!!! In particular, components should be designed in a generic manner, such that the "customization" can be done automatically. As an example, I manage the Clemson Ada Software Repository, which contains ADTs like Generic_Priority_Queue (among others). The user can dream up a new data type, define a few simple operations over the type (such as "=" and assignment), write a single line of code to do the instantiation, and voila: the user now has a new data type (a priority queue which can manage objects of the user's new type), and a considerable range of powerful operations over that queue, without ever looking at anyone else's implementation code; the entire process takes a grand total of about 5 minutes. > | Also, regarding the hardware analogy, it does not draw a direct > | correspondence between computer software and computer hardware; > | rather, it draws an analogy to the extensive catalogs of ICs, > | resistors, capacitors, etc. used by electrical engineers to build > | all kinds of application-specific products. > > Again, this assumes that the components can be used without modification. > This is not the norm with software, but is with hardware. Also, we must > keep in mind that resistors and capacitors implement one kind of machine. > For software, we must find the equivalents of resistors and capacitors for > each domain we write software for. Resistors and capacitors are domain-independent, and so it is with abstract data types such as B+ trees, linked lists, directed graphs, etc.; these are the resistors and capacitors of the software profession. There are also special-purpose ICs in the hardware industry, and these are the things which must be developed according to the methods described by Guillermo Arango in his brilliant article on Domain Analysis. The software equivalent of a special-purpose IC would be a package containing a set of domain-specific data types, functions, and procedures. Bill Wolfe, wtwolfe@hubcap.clemson.edu
billwolf%hazel.cs.clemson.edu@hubcap.clemson.edu (William Thomas Wolfe, 2847 ) (09/06/89)
From article <765@swbatl.UUCP>, by uucibg@swbatl.UUCP (3929): > Obviously, "engineering" is still an art too. Namely, it is the art of > examining a body of solutions to previous problems and trying to find one > or more solutions which can be adapted to solve the current problem. I > don't see any way to claim that this isn't still an art, since we would > have replaced all those engineers with computers if it weren't an art. There is a general progression which all fields go through: Art form => Engineering discipline => Hard Science The progress along this route is proportional to what is known about the field. The continuum indicates the progression from all heuristics (toward the left) to all deterministic solutions (toward the right); the fields which fall in between the two extremes are those for which heuristics are used to fill in the areas in which there still is not sufficient science. When a field is referred to as an engineering discipline, it means that informal heuristics are on the way to becoming an endangered species, and the software field is progressing very quickly in that direction. Bill Wolfe, wtwolfe@hubcap.clemson.edu
nagle@well.UUCP (John Nagle) (09/07/89)
The "reuse" concept is fundamentally flawed. Software components are not "reused", they are "used". This is to say that good software components are not leftovers from past projects, but units designed from the beginning to be components. They are productized, documented, and sold as components. There is a small but successful industry selling software components for microcomputers. Graphics packaged, database management packages, and communications packages seem to be the most common offerings. Having used a few of these products, my main observation is that using software components from multiple vendors tends to result in annoying problems. A typical problem stems from several components assuming that they can safely replace some standard portion of the standard C library (such as "printf" or "exit") with their own version. This is a good reason for only buying components for which one gets source code, so that such problems can be resolved. Another problem is incompatibility of components with new releases of other tools. When a new release of a C compiler comes out, it seems to be necessary, annoyingly, to upgrade some components at the same time. This can create problems, since the upgraded components may not be available for some time after the release of the compiler. Operating system releases can cause similar trouble. This can be a serious problem; in the worst case, dependence on a software component which is not being upgraded can result in the inability to continue work on a program. John Nagle
scotth@boulder.Colorado.EDU (Scott Henninger) (09/08/89)
|>From: billwolf%hazel.cs.clemson.edu@hubcap.clemson.edu (William Thomas Wolfe, 2847 ) | | The first problem that has to be overcome is the Not Invented | Here syndrome; we must have programmers who want to use components. | This can be addressed by training (at the university level), and | also by appeal to management (in the "real world"). To say this is to say that current reuse environments are adequate. They are not. The fact of the matter is that it is easier and takes less time to code it yourself than reuse existing code with current technology. Besides, and I repeat, *people are not aware of what reusable components exist*. This is primarily a tools problem, not a training problem. Training can only get you so far. Supporting tools must exist before people will practice what they are preached. It should also be noted that the NIH syndrome exists in any design discipline. To paraphrase Herbert Simon: "when designing artifacts for people, *do not postulate a new man*". The NIH syndrome is simply a part of human nature. You, President Bush, or anyone else, ARE NOT GOING TO CHANGE IT. Claiming that the "the problem has to be overcome" in this case makes the critical mistake of trying to change human nature. |> Secondly, once you've got a component, you must tailor it to your |> specific needs. This means understanding the code or some description |> of the code. Anyone who has debugged code written by others can attest |> to just how difficult this is. | | | Wonderful reasons for NOT DOING IT!!! In particular, components | should be designed in a generic manner, such that the "customization" | can be done automatically. Unfortunately, this is a yet unrealized goal. The fact of the matter is that designing generic code is extermely difficult and time consuming. And it will NEVER be able to handle all of the cases that programmers will come up with. The ability to tailor existing code is essential. | As an example, I manage the Clemson Ada | Software Repository, which contains ADTs like Generic_Priority_Queue | (among others). The user can dream up a new data type, define a few | simple operations over the type (such as "=" and assignment), write | a single line of code to do the instantiation, and voila: the user | now has a new data type (a priority queue which can manage objects | of the user's new type), and a considerable range of powerful | operations over that queue, without ever looking at anyone else's | implementation code; the entire process takes a grand total of | about 5 minutes. This is precisely my point. Whenever people talk about generic code, they inevitably give examples of *simple* ADTs; ones that you learn in your freshman programming class. I would argue that this would constitute an extermely small percentage of the code for, say, an accounting program, a user interface, or microcode for a tape drive. The extreme effort expended in creating a generic stack, queue, or whatever brings little savings to one trying to create a real application. | There are also special-purpose ICs in the hardware industry, and | these are the things which must be developed according to the methods | described by Guillermo Arango in his brilliant article on Domain Analysis. | The software equivalent of a special-purpose IC would be a package | containing a set of domain-specific data types, functions, and procedures. I agree with this in principle. What we have to avoid is making the arrogant statement that Computer Science will give us the ability to formalize all domains; i.e. succeed where others have been "failing" for tens, hundreds or thousands of years (all the way back to Plato). Guillermo's approach of "controlled approximations to *satisfycing* solutions" is exactly what I'm arguing for. Let me make a clarifying remark. I have always stated that the hardware analogy is *misleading* and is doing a great deal of harm to current thinking about software reuse. There are surface similarities, but the problem is much greater for software. A hardware engineer can flip through a few hundred pages of hardware component descriptions and find what he needs. Because software is so much more diverse than hardware, the number of potential components increases by orders of magnitude. This makes the problem *fundamentally* different - tools are needed to assist the programmer. -- Scott scotth@boulder.colorado.edu
ram@wb1.cs.cmu.edu (Rob MacLachlan) (09/09/89)
>From: billwolf%hazel.cs.clemson.edu@hubcap.clemson.edu (William Thomas Wolfe, 2847 ) >Subject: Re: Reasons for low reuse >Date: 5 Sep 89 21:40:24 GMT > > There is a general progression which all fields go through: > > Art form => Engineering discipline => Hard Science > > The progress along this route is proportional to what is known > about the field. This is a ridiculously sweeping generalization, and also one pretty discredited in philosophy-of-science circles. This "physics envy" has been a justification for much bad science (e.g. behaviorism.) As to the hardware analogy, I am not surprised non-technical managers find it seductive: oversimplifications usually are. It does show that it would be *nice* to have standard software components, but it doesn't show that it is possible. There is an illusory similarity because the analogy compares *computer* hardware and *computer* software. You could have said: "It takes only 47 kinds of screws to build an automobile, so we should be able to make do with 47 sofware components." But of course, that would sound silly... Rob
brucec@demiurge.WV.TEK.COM (Bruce Cohen;685-2439;61-028) (09/09/89)
In article <11449@boulder.Colorado.EDU> scotth@boulder.Colorado.EDU (Scott Henninger) writes: >Let me make a clarifying remark. I have always stated that the hardware >analogy is *misleading* and is doing a great deal of harm to current thinking >about software reuse. There are surface similarities, but the problem is >much greater for software. A hardware engineer can flip through a few >hundred pages of hardware component descriptions and find what he needs. >Because software is so much more diverse than hardware, the number of >potential components increases by orders of magnitude. This makes the >problem *fundamentally* different - tools are needed to assist the >programmer. > There is another reason why the hardware problem is simpler than the software: the hardware domain has been deliberately restricted to make standard components easy to specify. It's taken many years, but we have arrived at the point where any new family of components MUST adhere to a set of standard interfaces (five volt power supply, high-true logic, standard logic level voltage minima and maxima, etc., etc. Standardizing packages has enforced constraints on the partitioning of hardware systems (if you have only 40 pins, you can't transfer 200 signals directly). And the maximum manufacturable number of logic gates on a chip at a given time places a limit on what a designer will attempt on one chip; software size limitations are much more elastic. Beyond these standardizations is another one: most hardware designs these days are for digital transformers: widgets which take in a set of digital signals and put out another set in response. Market conditions typically dictate things like timing requirements, word size, etc. Similar constraints on software are again less demanding: ASCII for character representation does not really restrict the input much since there are so many possible meaningful combinations of characters in any useful input language. >-- Scott > scotth@boulder.colorado.edu "Men in padded bras don't look the same falling from high places." - R.A. McAvoy - "The Third Eagle" Bruce Cohen brucec@orca.wv.tek.com Interactive Technologies Division, Tektronix, Inc. M/S 61-028, P.O. Box 1000, Wilsonville, OR 97070
billwolf%hazel.cs.clemson.edu@hubcap.clemson.edu (William Thomas Wolfe, 2847 ) (09/10/89)
From article <13499@well.UUCP>, by nagle@well.UUCP (John Nagle): > Having used a few of these products, my main observation is that > using software components from multiple vendors tends to result in > annoying problems. A typical problem stems from several components > assuming that they can safely replace some standard portion of the > standard C library (such as "printf" or "exit") with their own version. > This is a good reason for only buying components for which one gets > source code, so that such problems can be resolved. Alternatively, you can use a language whose designers recognized the need for portability; Ada prohibits subsets and supersets, and issues validation certificates to compilers only after they have passed a rigorous validation suite; even then, the certificate is only good for about 18 months, at which point the compiler must face a newer, stronger validation suite if it is to obtain a new certificate. Bill Wolfe, wtwolfe@hubcap.clemson.edu
billwolf%hazel.cs.clemson.edu@hubcap.clemson.edu (William Thomas Wolfe, 2847 ) (09/10/89)
From scotth@boulder.Colorado.EDU (Scott Henninger): > To say this is to say that current reuse environments are adequate. They > are not. The fact of the matter is that it is easier and takes less time > to code it yourself than reuse existing code with current technology. Not true; the work required to repeat the design, implementation, and testing of a component is considerable. Furthermore, the component's implementation is likely to be considerably more sophisticated than the probable result of an attempt to do it from scratch. > Besides, and I repeat, *people are not aware of what reusable components > exist*. This is primarily a tools problem, not a training problem. My perspective is that if the market exists (i.e., if people are looking for components and wishing for better tools), the tools will spring up to meet the demand. Where people don't bother to look, the tools aren't going to appear courtesy of the Tool Fairy. > The NIH syndrome is simply a part of human nature. There are a great many cultures throughout the world which practice ideas which appear to be alien from the perspectives of other cultures. This does not imply that a baby from one of those other cultures could not be socialized into such a culture, such that the ostensibly alien practices seem perfectly natural. Hence, I suggest that professional training can be designed such that practices are internalized which preclude the possibility of rejecting an idea on the basis of its origin. > designing generic code is extermely difficult and time consuming. The engineering of ANY product is usually difficult and time-consuming, especially given that the designer of a generic component is trying to ensure a great many things that the user doesn't even know s/he needs. As a simple example, suppose that a user takes a component and uses it in a sequential application. Later, the application is maintained such that multitasking is introduced. Fortunately, the component's designer implemented the component such that multiple requests can be processed in parallel, while still maintaining serializability and recoverability. This demonstrates that the benefits of using a component can extend far beyond the initial construction of the application. Such an application will probably be of considerably higher quality than a corresponding application which did not make use of sophisticated software components. > And it will NEVER be able to handle all of the cases that programmers > will come up with. The ability to tailor existing code is essential. Given the existence of a highly sophisticated component, any user who tries to modify it will probably only get into trouble. It's much better to use the component in the implementation of a higher-level user-defined interface than to try to modify a component's implementation. > Whenever people talk about generic code, they inevitably give examples > of *simple* ADTs; ones that you learn in your freshman programming class. > I would argue that this would constitute an extermely small percentage of > the code for, say, an accounting program, a user interface, or microcode > for a tape drive. Domain-specific components will come with their own abstract data types, and will normally make considerable use of those types in the supplied procedures and functions. While it is certainly conceivable that generic parameters would prove useful in situations in which the domain-specific processing is performed on arbitrary data types, or using arbitrary user-defined procedures or functions, the fact that generic code is much more vital to the area of "container" ADTs has resulted in a short-term concentration of interest in that area. Also, some of the situations you describe are ones in which a different technique is applicable: packaging. An abstract interface will be constructed (e.g., a standard CRT (or CPU) interface), and the implementation of that package will translate those commands into whatever is necessary to implement them on a given hardware system. When porting the application it is only necessary to rewrite the machine-dependent parts of the system, which will have been segregated into the bodies of specific packages. The protection provided by the package specification will ensure that the rest of the application will remain unaffected. > Because software is so much more diverse than hardware, the number of > potential components increases by orders of magnitude. This makes the > problem *fundamentally* different - tools are needed to assist the > programmer. Tools *are* needed, but they won't sell if there isn't enough demand!! If organizations can be convinced to commit to a reuse program, then the tools will quickly follow. Bill Wolfe, wtwolfe@hubcap.clemson.edu
grichard@skiff.cis.ohio-state.edu (Golden Richard) (09/10/89)
Another (perhaps secondary) reason that I see for the current "low reuse" syndrome is the number of extremely sloppy components that are available. While working on a project at the University of New Orleans, we decided to "save time" and purchase a number of C components from a company in New Jersey (whose name I should actually mention, but I won't). To make a long story short, some of the development ended up taking 10X longer than if we had simply written everything ourselves. Bugs started to creep in and workarounds sometimes took days. I'm all for reusable software components, but some reasonably formal system of specifying *exactly* what the components do and a verification method for providing better than "a 50-50 chance" of the components meeting specs are absolutely necessary. A major problem with using someone else's code in object form is that, barring a rigorous specification, it's virtually impossible to ascertain *exactly* what a component does. Having source is helpful, but who wants to poke through hundreds (thousands?) of pages of code "verifying" functionality? -=- Golden Richard III OSU Department of Computer and Information Science grichard@cis.ohio-state.edu "I'm absolutely positive! ...or not."
simpson@trwarcadia.uucp (Scott Simpson) (09/12/89)
In article <60116@tut.cis.ohio-state.edu> Golden Richard <grichard@cis.ohio-state.edu> writes: >I'm all for reusable software components, but some reasonably formal system >of specifying *exactly* what the components do and a verification method >for providing better than "a 50-50 chance" of the components meeting specs >are absolutely necessary. A major problem with using someone >else's code in object form is that, barring a rigorous specification, it's >virtually impossible to ascertain *exactly* what a component does. I've been reading Bertrand Meyer's book, and one of the ways Eiffel enforces correctness is by specifying semantic assertions that must be met by routines in a class. Eiffel uses preconditions (require), postconditions (ensure) and class invariants (invariant). Preconditions and postconditions must only be met at the beginning and end of a routine. Class invariants must be met at all "stable" times (between routine calls). If you don't meet an assertion, an exception is raised. Also, hiers to a class must meet all the assertions of its parent, so you can't change behavior by inheriting. For example, the ADT for a stack may look like (this is not Eiffel, just an ADT spec) TYPES -- Syntax STACK[X] -- Generic stack with type X FUNCTIONS -- Syntax empty: STACK[X] -> BOOLEAN --Accessor function. Stack on left new: -> STACK[X] --Creation function. Stack on right push: X x STACK[X] -> STACK[X] --Transformer function. --Stack on both sides. pop: STACK[X] /-> STACK[X] --Transformer. /-> denotes --partial function. I.e., --function doesn't work for --all values (like stack --empty) top: STACK[X] /-> X --Accessor PRECONDITIONS -- Semantics. Clarifies partial functions. pre pop(s:STACK[X]) = (not empty(s)) pre top(s:STACK[X]) = (not empty(s)) AXIOMS -- Semantics For all x:X, s:STACK[X]: empty(new()) not empty(push(x,s)) top(push(x,s))=x pop(push(x,s))=s There is a lot of information there that specifies exactly how a stack behaves. You can model virtually all of this in Eiffel. Here is an Eiffel implementation: class STACK[T] export push, pop, top, empty, nb_elements, empty, full -- What clients can see feature implementation: ARRAY[T]; max_size: INTEGER; nb_elements: INTEGER; Create(n:Integer) is -- Allocate stack for maximum of n elements -- (or for no elements if n < 0) do if n>0 then max_size := n end; implementation.Create(1, max_size) end; -- Create empty : BOOLEAN is -- Is stack empty? do Result := (nb_elements = 0) end; -- empty full : BOOLEAN is -- Is stack full? do Result ;= (nb_elements = max_size) end; -- full pop is -- Remove top element require -- Precondition! not empty -- i.e. nb_elements > 0 do nb_elements := nb_elements - 1 ensure -- Postcondition! not full; nb_elements = old nb_elements - 1 end; -- pop top : T is -- Top element require not empty -- i.e. nb_elements > 0 do Result := implementation.entry(nb_elements) end; -- top push(x : T) is -- Add x on top require not full -- i.e. nb_elements<array_size in this representation do nb_elements := nb_elements + 1; implementation.enter(nb_elements, x) ensure not empty; top = x; nb_elements = old nb_elements + 1 end; -- push invariant -- These always must satisfied at stable states. 0 <= nb_elements; nb_elements <= max_size; empty = (nb_elements = 0) end -- class STACK The only AXIOM that is not ensured by this code is pop(push(x,s)) = s so you can see that enforcing correctness can be facilitated by the use of assertions. Scott Simpson TRW Space and Defense Sector usc!trwarcadia!simpson (UUCP) trwarcadia!simpson@usc.edu (Internet)
garym@ulysses.UUCP (Gary Murphy) (09/12/89)
In article <60116@tut.cis.ohio-state.edu> Golden Richard <grichard@cis.ohio-state.edu> writes: >Another (perhaps secondary) reason that I see for the current "low reuse" >syndrome is the number of extremely sloppy components that are available. >...[an example of buying object code] ... A major problem with using someone >else's code in object form is that, barring a rigorous specification, it's >virtually impossible to ascertain *exactly* what a component does. Having >source is helpful, but who wants to poke through hundreds (thousands?) of >pages of code "verifying" functionality? I've had similar experiences with C library functions packaged with a compiler, with 3rd party code that uses 'slightly' variant library functions, and some OOP systems where the interface is formally spelled out but the rest kept elsewhere - in all three cases, I've either needed to hunt down the real source or waste a great deal of time probing a black box. In this day and age, few programmers would even poke through the lines they wrote themselves without a symbolic debugger and if source is included, all it takes is a single re-compile to create the step-able version. And speaking of reuse, and this problem of source-code secrets, how does this sit with the misplaced metaphor of software-as-literature with respect to copyrights? (If I quote Tolstoy's first edition, and the passage is stated contrarily in the fifth, do I still owe royalties? :-). -- Gary Murphy - Cognos Incorporated - (613) 738-1338 x5537 3755 Riverside Dr - P.O. Box 9707 - Ottawa Ont - CANADA K1G 3N3 e-mail: decvax!utzoo!dciem!nrcaer!cognos!garym Cosmic Irreversibility: 1 pot T -> 1 pot P, 1 pot P /-> 1 pot T
dwiggins@atsun.a-t.com (Don Dwiggins) (09/13/89)
Being real process-oriented lately, I'd like to put this reuse discussion in a broader setting. Many assertions have been made about the possibilities and issues of reuse, each based on unstated or only partially stated assumptions about the process and setting of the supposed act of reuse. In fact, there can be many such settings, each implying different constraints and characteristics of the components, the collection of them, and the "reuser". For example, The personal toolkit: an experienced machanic collects high-quality tools, assumes responsibility for them, and takes them with him/her. Having created a module to solve a problem, an experienced software engineer might well generalize the solution a bit, polish the implementation and the interface description, and drop it in the kit. The corporate resource: rather than continually reinventing solutions to recurring problems, the company creates a library and supporting staff to capture the solutions and make them available to new projects. Note that there's likely some domain leverage here; the company's projects will often cover a lot of the same ground. The commercial product: this is what seems to have been the assumption behind most of the discussions so far. Even here, there are many possible relationships among the component and library creators, sellers, and buyers, and probably many possible types of "component" (how about selling detailed designs or generic sources like MacApp?) In all these settings, I think that the major problems are organizational, psychological, and institutional -- meeting the differing goals of the various folks involved. It'll probably take some "process prototyping" to work these out. The technical problems that arise will be solved as part of all this (and some technical issues will turn out to be non-problems). What I'd like to see is some reuse success and horror stories along this line: what was the setting and process, how did it work out, what problems arose and how were they solved (if they were)? -- Don Dwiggins "Solvitur Ambulando" Ashton-Tate, Inc. dwiggins@ashtate.uucp
hopper@ntmtv.UUCP (Ian Hopper) (09/13/89)
I have always felt that some form of Garbage Collection is needed in order to do a decent job on reusable "Collection" modules. Since the current favorite language (C++) does not consistiently (or easily) support GC, we do not see good quality collection modules. I believe the Smalltalk books come to the same conclusion, but neither Smalltalk nor it's creators are perfect. The classic approach would be to copy-in and copy-out the contents of such containers, but simply passing pointers to contents is often much faster. Do we focus our efforts on languages that have garbage collection, or are we forced to use the copy-in/copy-out approach? Regrettably, the USING code is quite different in the various cases. Looking forward to responses, -- Ian Hopper PS: Writers of collection modules in GC-based environments should not forget to create dynamically-expanding versions of their collections. It is very annoying to have to estimate the size of collections in advance, things always blow up on large data sets.
scotth@boulder.Colorado.EDU (Scott Henninger) (09/16/89)
|>From: hopper@ntmtv.UUCP (Ian Hopper) | |I have always felt that some form of Garbage Collection is |needed in order to do a decent job on reusable "Collection" |modules. Since the current favorite language (C++) does |not consistiently (or easily) support GC, we do not see |good quality collection modules. Quality in what sense? Program efficiency? Cognitive efficiency (i.e. how readable it is)? Correctness? Reliability? -- Scott scotth@boulder.colorado.edu
ram@wb1.cs.cmu.edu (Rob MacLachlan) (09/18/89)
>From: hopper@ntmtv.UUCP (Ian Hopper) >Newsgroups: comp.sw.components >Subject: Re: Reasons for low reuse >Date: 13 Sep 89 03:43:32 GMT > >I have always felt that some form of Garbage Collection is >needed in order to do a decent job on reusable "Collection" >modules. [...] > >The classic approach would be to copy-in and copy-out the contents >of such containers, but simply passing pointers to contents is >often much faster. > >Do we focus our efforts on languages that have garbage collection, >or are we forced to use the copy-in/copy-out approach? Regrettably, >the USING code is quite different in the various cases. It seems to me that once you admit dynamic allocation into the language, one must at least concede the \desirability/ of having GC. The only question is whether the cost of supporting GC is excessive. There are two costs that I see: 1] A performance penalty due to GC time and tag manipulation. Unless GC support is controlled by a compiler switch, some of this overhead is also present in programs that don't use GC. GC can also cause unpredicable delays. 2] At the language level, a certain discipline in pointer use is required so that the garbage collector can locate pointers and not be confused by random data that might be a pointer. Being a Lisp programmer, it is understandable that I don't find either of these costs prohibitive. The performance penalty isn't as much as people suppose: a lot of progress has been made in GC algorithms in the past ten years, and these algorithms have recently begun to see practical use in languages such as Lisp, Smalltalk and ML. Also, as you hinted at above, there are often hidden efficiencies that can only be safely realized in systems that support GC. So far as the language style issue, this isn't a big problem for high-level languages other than C. I think that Lisp is a constructive proof of the reuse potential in systems that support "generic types", GC and first-class functions (e.g. procedures in records, etc.) As many whining system managers will tell you, Lisp systems are big. That bigness is mainly because a Lisp image has lots of code in it; Lisp programs tend to have big working sets because lots of that code is used. Coming from a Lispy language perspective, the main challenge is not to make the system smaller, but to make it bigger so that there is more stuff out there that the programmer can use. (Of course, we want to maintain similar cost-effectiveness, rather than just bloating with junk.) >PS: Writers of collection modules in GC-based environments should not >forget to create dynamically-expanding versions of their collections. >Itis very annoying to have to estimate the size of collections in >advance, things always blow up on large data sets. Yep, this is often something that we have to flame new Lisp programmers for when we are breaking them in. Of course, if you use a linked-list implementation of your data structures, this happens for free. Rob
hopper@ntmtv.UUCP (Ian Hopper) (09/20/89)
From article <11701@boulder.Colorado.EDU>, by scotth@boulder.Colorado.EDU (Scott Henninger): > |>From: hopper@ntmtv.UUCP (Ian Hopper) > | > |I have always felt that some form of Garbage Collection is > |needed in order to do a decent job on reusable "Collection" > |modules. Since the current favorite language (C++) does > |not consistiently (or easily) support GC, we do not see > |good quality collection modules. > > Quality in what sense? Program efficiency? Cognitive efficiency (i.e. how > readable it is)? Correctness? Reliability? > > -- Scott > scotth@boulder.colorado.edu That is a perfectly reasonably question, given my vague posting. Sorry to waste your time on the first pass. (Novice poster.) All of your suggesions apply, I would say. Performance can be an application specific issue, so is GC. I interpret "quality" in a reusable package to mean: lack of internal bugs and an interface that allows the package to be used without hassles. Typical hassles are listed as items 2-5 below. The (unstated) question I am getting at is: do we need to assume mark-and-sweep-like garbage collection in order to write siginificant amounts of reusable software? One disclaimer: I don't have a copy of the Gorlan "OOPS" C++ library, so I am forced to speculate on what is available from it. I did not wish to imply that it (or any other particular library) is broken or "bad", rather that such "good" implementations are difficult, and there are very few of them around. Only OOPS is in a language without a standard garbage collector. The others have GC's: Smalltalk and Eiffel. Eiffel has a GC, but the classes suffer from the fixed-at-creation problem my "PS" was referring to. Smalltalk may not have the performance that some applications need and lacks static type checking. I believe that one of the following apply to a reusable collection "mocule": 1) There is a mark-and-sweep garbage collector available. I claim this is "best", provided you can afford GC. I know if several GC's that ease the "hiccups" that the classic M-S approach required. 2) The library implements a mark-sweep garbage collector. Perhaps restricting the gc capability to objects that comply with some restrictions. This is OK, but there are restrictions on use. M-S garbage collectors are often not portable. 3) The library uses some form of reference counting and punts the problem of circular references to the client of the library. If circular references are provably not a problem for the particular case, then this is perfect. Again, there may be additional restrictions on what sorts of objects can be put into a collection. (SubClass of: ReferenceCountableObject.) 4) The library copies collection elements into and out of the collection objects. This is slow for contents that are large objects in their own right. Putting an object into and then retrieving that object creates a copy, rather than the original object. This may be inappropriate. Objects cannot tell whether they are a member of a collection, except by value. Membership in multiple collections is not easily represented, except by value. 5) The collection class forces it's users to carefully track the "ownership" of objects. This makes it difficult to allow an object to be a member of a varying number of collections without extra book-keeping. The source of many subtle bugs in user's code. I believe that this is the "typical" approach. (Still :) Interested in responses, Ian