[comp.lang.ada] Software Reuse -- do we really know what it is ?

craig@dcl-cs.UUCP (06/18/87)

There have been a couple of articles recently on Software Reuse and its
likely acceptance by Defence Contractors.  In considering Software Reuse in
general, not just with reference to Ada and DoD, do we know what it is ?
The scale of software that Ada allows the programmer to reuse seems to be
primarily that of the package (in Modula-2  the Module). Is this sufficient?
If we leave aside for the time being the question of whether Ada is an object
oriented language and accept that if it isn't then you can do a reasonably
good job faking it, reuse in Ada seems to be stuck at the level of the
Abstract data type. Furthermore the lack of any easy (or apparent) way to 
derive WHAT an Ada program is doing rather than HOW it is doing it ,
does put a large amount of the responsibility for recovering reusable
components on the programmer.

In summary I would like to offer a few statements for discussion
to see if we can clarify reuse.

1.	We don't really know what it is.

2.	It probably isn't a thing at all, but rather a collection of things
	depending on the scale at which the reuse is to take place.

3.	Languages such as Ada and Modula-2, and imperative languages in
	general are unsuitable for writing reusable software because of
	their concentration on the HOW rather than the WHAT.	

4.	Reuse of Design isn't considered at all by any current applications
	language.

5.	Nobody can force programmers to write good reusable code.

6.	Even if they do write reusable code how the **** do we ever find it
	again so that we can reuse it ?


All responses appreciated.

Craig.

-- 
UUCP:	 ...!seismo!mcvax!ukc!dcl-cs!craig| Post: University of Lancaster,
DARPA:	 craig%lancs.comp@ucl-cs          |	  Department of Computing,
JANET:	 craig@uk.ac.lancs.comp           |	  Bailrigg, Lancaster, UK.
Phone:	 +44 524 65201 Ext. 4476   	  |	  LA1 4YR

crowl@rochester.arpa (Lawrence Crowl) (06/22/87)

In article <371@dcl-csvax.comp.lancs.ac.uk>
craig@comp.lancs.ac.uk (Craig Wylie) writes:
>...  The scale of software that Ada allows the programmer to reuse seems to be
>primarily that of the package. Is this sufficient?

Personal opinion:  It is not.  The mechanism is sufficient if the programmer
of a package is very thorough and very disciplined.  However, programmers are
often under too much presure to be so.

Modula-II mechanisms are insufficient because they do not provide generics.

>1.	We don't really know what it is.

Well, I find a glimering of re-use in reading Knuth's books.  I will point at
an analogy though.  Board level designers constantly use circuits designed by
others.  They are packaged in integrated circuits.

>2.	It probably isn't a thing at all, but rather a collection of things
>	depending on the scale at which the reuse is to take place.

I agree.  However, I consider discipline and investment as necessary things.

>3.	Languages such as Ada and Modula-2, and imperative languages in
>	general are unsuitable for writing reusable software because of
>	their concentration on the HOW rather than the WHAT.

Clearly, we need more concentration on WHAT, but we should not abandon the
efficiency of HOW.

>4.	Reuse of Design isn't considered at all by any current applications
>	language.

The separation of abstract type from implementation in Trellis/Owl and Emerald
helps.  In addition the pre/post conditions of Eiffel provide some (though
not enough) facilities for ensuring the WHAT.  (See Proceedings OOPSLA'86 in
the November 1986 SIGPLAN.)

>5.	Nobody can force programmers to write good reusable code.

True.  But no one need buy code that is not both good and reusable.  I believe
there is a market for such code.

>6.	Even if they do write reusable code how the **** do we ever find it
>	again so that we can reuse it ?

Well, libraries do a somewhat reasonable job of reusing intellectual work in
other forms.  Perhaps they could be drafted into this task also.
-- 
  Lawrence Crowl		716-275-5766	University of Rochester
			crowl@rochester.arpa	Computer Science Department
 ...!{allegra,decvax,seismo}!rochester!crowl	Rochester, New York,  14627

shebs@utah-cs.UUCP (Stanley Shebs) (06/22/87)

In article <374@sol.ARPA> crowl@rochester.UUCP (Lawrence Crowl) writes:
>In article <371@dcl-csvax.comp.lancs.ac.uk>
>craig@comp.lancs.ac.uk (Craig Wylie) writes:
>>1.	We don't really know what it is.
>
>Well, I find a glimering of re-use in reading Knuth's books.  I will point at
>an analogy though.  Board level designers constantly use circuits designed by
>others.  They are packaged in integrated circuits.

An interesting analogy.  It says a lot about prevailing software culture:

1. Available chips do not always meet requirements exactly.  For instance,
a board might need 3 NAND gates, but the 7400 has 4.  EEs just ignore the
extra gate, or tie its pins to something stable.  In a similar situation,
software people fume and gnash their teeth over "wasted space".

2. Running wires around boards loses some performance, relative to cramming
everything onto a single chip.  All the techniques for modules, objects, etc,
tend to slow things down.  Again, software types tear their hair out and
vow to recode everything into one assembly language procedure.  Worse, other
software types admire them for doing so!  Come to think of it, the advent
of VLSI tools promotes the same idea for hardware, and we're seeing lots of
specialized chips these days...

>>3.	Languages such as Ada and Modula-2, and imperative languages in
>>	general are unsuitable for writing reusable software because of
>>	their concentration on the HOW rather than the WHAT.
>
>Clearly, we need more concentration on WHAT, but we should not abandon the
                                                  ^^^^^^^^^^^^^^^^^^^^^^^^^
>efficiency of HOW.
 ^^^^^^^^^^

QED!

3. In general, hardware types have standards for every imaginable sort of
interface, and they stick to them remarkably well.  You can plug boards into
a standard bus with only a small chance of sparks flying everywhere as the
boards fry.  In software, standards are strictly for lip service to managers;
only a novice would consider combining programs from several different
sources without planning a few hours or days of debugging!

In short, I believe there are no technical problems or issues with reuse;
it's the software culture that has to change.  At present, the prevailing
attitude is that the densely-coded, highly-optimized, do-everything program
is a sort of ideal to which everyone aspires.  Until this attitude changes,
software reusability will continue to be a bad joke among those who actually
write programs.

>>5.	Nobody can force programmers to write good reusable code.
>
>True.  But no one need buy code that is not both good and reusable.  I believe
>there is a market for such code.

Manufacturers seem to think their interest is in maintaining secrecy of code.
Customers only care about speed and features.  Read Infoworld and see if they
ever say anything positive about a program that is slower but more modular.

>  Lawrence Crowl		716-275-5766	University of Rochester

							stan shebs
							shebs@cs.> ie do-r

crowl@rochester.arpa (Lawrence Crowl) (06/22/87)

In article <4658@utah-cs.UUCP> shebs@utah-cs.UUCP (Stanley Shebs) writes:
]... software people fume and gnash their teeth over "wasted space". ...  All
]the techniques for modules, objects, etc, tend to slow things down.  Again,
]software types tear their hair out and vow to recode everything into one
]assembly language procedure.  Worse, other software types admire them for
]doing so!  ...
]
]In article <374@sol.ARPA> crowl@rochester.UUCP (Lawrence Crowl) writes:
>>In article <371@dcl-csvax.comp.lancs.ac.uk>
>>craig@comp.lancs.ac.uk (Craig Wylie) writes:
)))3.	Languages such as Ada and Modula-2, and imperative languages in
)))	general are unsuitable for writing reusable software because of
)))	their concentration on the HOW rather than the WHAT.
>>
>>Clearly, we need more concentration on WHAT, but we should not abandon the
]                                                  ^^^^^^^^^^^^^^^^^^^^^^^^^
>>efficiency of HOW.
] ^^^^^^^^^^
]
]QED!

Let me clarify my position.  I can specify a sort as a set of predicates and
let the system figure out how to satisfy those predicates.  This is the WHAT
approach used in languages such as Prolog.  Another approach is to write a
algorithm for sorting, e.g. quicksort.  This is the HOW approach used in
languages such as Ada.  Yes, the packaging of the sort will result in some
loss of efficiency.  However, it will be substantially faster than the WHAT
approach.  I am advocating an approach in which a package interface describes
WHAT and the implementation of the package describes HOW.

Because I wish to keep the macro-efficiency of algorithmic languages, do not
accuse me of wishing to keep the micro-efficiency of hand-tuned assembler.

]3. In general, hardware types have standards for every imaginable sort of
]interface, and they stick to them remarkably well.  You can plug boards into
]a standard bus with only a small chance of sparks flying everywhere as the
]boards fry.  In software, standards are strictly for lip service to managers;
]only a novice would consider combining programs from several different
]sources without planning a few hours or days of debugging!

Programmers to this sort of program combination many times a day in the Unix
shell.  There ARE approaches to software reuse that CAN work.  We need to
provide this kind of capability within a language.

]In short, I believe there are no technical problems or issues with reuse;
]it's the software culture that has to change.  At present, the prevailing
]attitude is that the densely-coded, highly-optimized, do-everything program
]is a sort of ideal to which everyone aspires.  Until this attitude changes,
]software reusability will continue to be a bad joke among those who actually
]write programs.

There are technical problems.  For instance, how do you insure that the 
parameters to a generic package are appropriate.

Performance will always be a goal.  However, it must be balanced against cost.
Most programming done today is in a high-level language.  In the early sixties,
most programming was done in assembler.  So, the software attitude has changed.

Modular code also allows changes in representation that can lead to orders of
magnitude performance improvements.  Non-modular code strongly inhibits such
representational changes.  In short, the micro-efficiency of non-modular code
leads to the macro-INefficiency of poor algorithms and representations.

)))5.	Nobody can force programmers to write good reusable code.
>>
>>True.  But no one need buy code that is not both good and reusable.  I
>>believe there is a market for such code.
]
]Manufacturers seem to think their interest is in maintaining secrecy of code.

Again, let me clarify.  I meant that the reusable software would be written by
software houses and sold to companies which write applications.  For instance,
Reusable Software Inc. sells a sort package to Farm Software Inc. which uses
it in its combine scheduling program.  Farm Software Inc. need not divulge its
algorithms or its use of packages written by Reusable Software Inc.

]Customers only care about speed and features.  Read Infoworld and see if they
]ever say anything positive about a program that is slower but more modular.

You forgot cost.  Modular code will cost substantially less in the long run.
-- 
  Lawrence Crowl		716-275-5766	University of Rochester
			crowl@rochester.arpa	Computer Science Department
 ...!{allegra,decvax,seismo}!rochester!crowl	Rochester, New York,  14627

shebs@utah-cs.UUCP (Stanley Shebs) (06/23/87)

In article <378@sol.ARPA> crowl@rochester.UUCP (Lawrence Crowl) writes:

>>>Clearly, we need more concentration on WHAT, but we should not abandon the
>]                                                  ^^^^^^^^^^^^^^^^^^^^^^^^^
>>>efficiency of HOW.
>] ^^^^^^^^^^
>]
>]QED!
>
>Let me clarify my position.  I can specify a sort as a set of predicates and
>let the system figure out how to satisfy those predicates.  This is the WHAT
>approach used in languages such as Prolog.  Another approach is to write a
>algorithm for sorting, e.g. quicksort.  This is the HOW approach used in
>languages such as Ada.  Yes, the packaging of the sort will result in some
>loss of efficiency.  However, it will be substantially faster than the WHAT
>approach.  I am advocating an approach in which a package interface describes
>WHAT and the implementation of the package describes HOW.
>
>Because I wish to keep the macro-efficiency of algorithmic languages, do not
>accuse me of wishing to keep the micro-efficiency of hand-tuned assembler.

I wasn't accusing anybody of anything, just pointing out that like any other
culture, the software culture is very pervasive and people in it (us) don't
always recognize when we're behaving according to those cultural norms.
For instance, if I were to post some inefficient sort to the net, there are
maybe ten computer people in the world who could look at it and not get at
least a twinge of "Gee, why not use a better algorithm?"  As I said,
it's part of the culture.  Not completely bad, but frequently dominates
our thinking.

Your typical serious C hacker will get unhappy about the overhead of a
function call, let alone the extra functions involved in "packaging"!
After several years of extensive Lisp hacking, I've managed to overcome
resistance to defining lots of little data abstraction functions, and
only feel guilty once in a while :-).  An additional obstacle to using
the "packaging" is that in the past, some systems (such as Simula and
Smalltalk) were orders-of-magnitude slower than procedural languages,
and there is perhaps a lingering perception that data abstraction costs
a lot in performance.

Requiring both WHAT and HOW is a pretty controversial thing to do.  The
biggest problem to me is the potential for inconsistency, since many things
will be stated twice, but in different terms.  That's the rationale for
making the computer figure out the HOW itself, but that is an elusive and
perhaps unreachable goal.  (Doesn't stop me from trying though!)

>Programmers [do] this sort of program combination many times a day in the Unix
>shell.  There ARE approaches to software reuse that CAN work.  We need to
>provide this kind of capability within a language.

Unix is a counterexample, that's why I didn't mention it :-).  A closer look
is worthwhile.  Unix tools offer basically one interface - a stream of bytes.
More complicated interfaces, such as words, nroff commands, or source code,
are less well supported; it's unusual to be able to pass C source through
many filters in the way that data files can be passed.  Also, at least in the
groups of Unix users I've observed, pipes and filtering sequences longer
than about 3 stages are relatively uncommon, and are about as difficult
for many people to compose as a C program.  Of course, my sample is not
scientific, and I'm sure there are lots of Unix hacks that will be glad
to tell me all about their 15-stage pipe processes!

What other *working* approaches are there?

>There are technical problems.  For instance, how do you insure that the 
>parameters to a generic package are appropriate.

Use something higher-level than Ada?  This seems like an issue only for
some languages, not a major obstacle to reuse.

>Performance will always be a goal.  However, it must be balanced against cost.
>Most programming done today is in a high-level language.  In the early sixties,
>most programming was done in assembler.  So, the software attitude has changed.

This is how us language people justify our salaries.  On the other hand, I've
been wondering if the change was caused by other factors not directly related
to level of language, such as sites getting a wider variety of hardware (thus
making non-portable assembly language impractical).  C is very popular for
new applications nowadays, but many consider C to be a "portable assembly
language".

>Modular code also allows changes in representation that can lead to orders of
>magnitude performance improvements.  Non-modular code strongly inhibits such
>representational changes.  In short, the micro-efficiency of non-modular code
>leads to the macro-INefficiency of poor algorithms and representations.

I agree 100% (especially since my thesis relates to this!)  BUT, flaming
about the wonders of data abstraction is not going to change anybody's
programming practices.  Demonstrations are much more convincing, although
a DoD project to demonstrate reusability is probably much less influential
than Jon Bentley's CACM column.  Many recent C books have been introducing
substantial libraries for reuse, although the books' stated policies on
copying are not consistent.  More of this sort of thing would be great.

>Again, let me clarify.  I meant that the reusable software would be written by
>software houses and sold to companies which write applications.  For instance,
>Reusable Software Inc. sells a sort package to Farm Software Inc. which uses
>it in its combine scheduling program.  Farm Software Inc. need not divulge its
>algorithms or its use of packages written by Reusable Software Inc.

I hadn't thought about that.  Here's my reaction as a Farm Software Inc.
programmer - "How do I know if their stuff is good enough!? ... But the 
interface isn't right! ... How can we fix the bugs without sources!"
Reuse can't happen until the seller *guarantees* critical characteristics -
they have to be able to say that their sort package will sort M data values
in N seconds, and that the software will have bugs fixed within a certain
number of days of being discovered, and so forth.  This is old hat for other
kinds of engineers, but software companies these days will only promise that
there is data on the disk somewhere :-(.  (I'm sure there are places that will
certify performance - anybody got good examples?)

>[...] Modular code will cost substantially less in the long run.

I sort of believe that too, but it's hard to substantiate.  Anecdotes are
easy to come by, but this is a field where cost depends primarily on
programming skill, and we don't have a precise measure of that skill.
The other cost win is when a module can be used in some other program,
but the extra cost of making code reusable can only be justified if your
company has another program to use it in!

BTW, at Boeing I proposed an engineer-maintained library of aerospace-related
subroutines, so people didn't have to continually reinvent spherical
geometry formulas, Zakatov equations, and the like.  But management
rejected the idea, because it would be "too difficult to coordinate"
(it was supposed to cut across individual projects).  No mention of costs...

People interested in promoting software reuse should look at how expert
systems developed as a field.  Although the first ones appeared in the
mid-70s, it wasn't until 1980 when the expert system R1 that configured
Vaxen for DEC was published.  DEC claimed to have saved millions of dollars
in the first year of using it.  From then on, the expert system business
grew exponentially, although it's not clear whether anybody else has ever
profited from an expert system so dramatically...

>  Lawrence Crowl		716-275-5766	University of Rochester

							stan shebs
							shebs@cs.utah.edu

ijd@camcon.co.uk (Ian Dickinson) (06/29/87)

> Xref: camcon comp.lang.ada:166 comp.lang.misc:164
 
Clearly from foregoing discussions,  software re-use at the code level does
present significant problems:
	* there is a trade-off - sometimes quite severe - between generality
	  and efficiency

	* we can never be quite sure of the routine doing exactly what we need
	  in a given circumstance

	* management of libraries is difficult, as is retrieval

	* routines in one language are not portable (without effort) to
	  another.

So what's the _real_ problem?  I think that we are trying to define re-use at 
too *low* a level.  What we really want to re-use are ideas - algorithms,
standard ways of performing defined operations, etc,.

Hence a solution:  we somehow encode _abstractions_ of the ideas and place
these in the library - in a form which also supplies some knowledge about the
way that they should be used.  The corollary of this is that we need more
sophisticated methods for using the specifications in the library.  
(Semi)-automated transformations seem to be the answer to me.

Thus we start out with a correct (or so assumed) specification,  apply
correctness-preserving transormation operators,  and so end up with a correct
implementation in our native tongue (Ada, Prolog etc, as you will).  The
transformations can be interactively guided to fit the precise circumstance.

The advantages are:
	* library specifications are easier to understand,  hence easier to
	  maintain

	* the library can contain a smaller number of more general routines,
	  since essentially similar operations can be encoded as one library
	  entry

	* the additional knowledge can be used to provide an intelligent
	  interface for browsing and retrieval

	* routines can be transformed to many different languages.


I see this field as essentially a synthesis between AI and software 
engineering,  and potentially of benefit to both.

[Credit]  I originally got this idea from my supervisor: Dr Colin Runciman
@ University of York.  I have been tinkering around with it in my spare time
a bit since then.  Who knows,  maybe one day I'll get to work on it
seriously (dream on :-) !!).
-- 
| Ian Dickinson    Cambridge Consultants Ltd, AI group    (0223) 358855[U.K.] |
| uucp:    ...!seismo!mcvax!ukc!camcon!ijd               or:  ijd%camcon.uucp |
>>  To dance is to live,  but the dance of life requires many strange steps  <<
>>      Disclaimer:  All opinions expressed are my own (surprise!).          <<

adams@crcge1.UUCP (Drew Adams) (07/02/87)

Let me play provocateur and recommend a little known paper introducing 
another point of view regarding software reusability and modularity:

Hughes, John, "Why Functional Programming Matters", Report 16, Programming
		Methodology Group, University of Goteborg and Chalmers
		University of Technology, Goteborg, Sweden, 1984,
		ISSN 0282-2083

Here's the abstract:

	As software becomes more and more complex, it is more and more 
	important to structure it well.  Well-structured software is easy 
	to write, easy to debug, and provides a collection of modules that 
	can be re-used to reduce future programming costs.  Conventional 
	languages place conceptual limits on the way problems can be 
	modularised.  [Purely f]unctional languages push those limits back.  
	In this paper we show that two features of functional languages in 
	particular, higher-order functions and lazy evaluation, can contribute
	greatly to modularity.  As examples, we manipulate lists and trees, 
	program several numerical algorithms, and implement the alpha-beta 
	heuristic (an algorithm from Artificial Intelligence used in 
	game-playing programs).  Since modularity is the key to successful 
	programming, functional programming is vitally important to the real 
	world.

Hughes argues that the usual "advantages" of declarative languages over
imperative ones (no assignment, no side effects, no flow of control) 
are negative expressions of some of the problems with imperative
languages, but that they leave unexplained 1) why these problems are 
problems and, more importantly, 2) what are the real POSITIVE advantages
of declarative programming.  To quote from the introduction:

	If omitting assignment statements brought such enormous benefits
	then FORTRAN programmers would have been doing it for twenty years.
	It is a logical impossibility to make a language more powerful by
	omitting features, no matter how bad they may be.

	Even a functional programmer should be dissatisfied with these 
	so-called advantages, because they give him no help in exploiting 
	the power of functional languages.  One cannot write a program which
	is particularly lacking in assignment statements, or particularly 
	referentially transparent.  There is no yardstick of program quality
	here, and therefore no ideal to aim at.

	Clearly this characterisation of functional programming is inadequate.
	We must find something to put in its place - something which not only
	explains the power of functional programming, but also gives a clear
	indication of what the functional programmer should strive towards.

Hughes finds that the importance of functional languages is that they allow 
program modularisation in ways which imperative languages cannot.  
To quote again:

	... recent languages such as Modula-II [Wirth 82] and Ada [DOD 80]
	include features specifically designed to help improve modularity.
	However, there is a very important point that is often missed.  
	When writing a modular program to solve a problem, one first 
	divides the program into sub-problems, then solves the sub-problems
	and combines the solutions.  The ways in which one can divide up the
	original problem depend directly on the ways in which one can glue
	solutions together.  Therefore, to increase one's ability to 
	modularise a problem conceptually, one must provide new kinds of 
	glue in the programming language.  

	... functional languages provide two new, very important kinds of
	glue [(higher order functions and lazy interpretation)]....
	This is the key to functional programming's power - it allows 
	greatly improved modularisation.  It is also the goal for which 
	functional programmers must strive - smaller and simpler and more
	general modules, glued together with the new glues....

If you only read one article about (purely) declarative languages, let it
be this one.  You won't be disappointed.-- 
Drew ADAMS, Laboratoires de Marcoussis, Centre de Recherche de la Compagnie 
            Generale d'Electricite, Route de Nozay, 91460 MARCOUSSIS, FRANCE
            Tel. 64.49.11.54, adams@crcge1.cge.fr

jbn@glacier.STANFORD.EDU (John B. Nagle) (07/05/87)

     The trouble with this idea is that we have no good way to express
algorithms "abstractly".  Much effort was put into attempting to do so 
in the late 1970s, when it looked as if program verification was going to
work.  We know now that algebraic specifications (of the Parnas/SRI type)
are only marginally shorter than the programs they specify, and much
less readable.  Mechanical verification that programs match formal
specifications turned out not to be particularly useful for this reason.
(It is, however, quite possible; a few working systems have been 
constructed, including one by myself and several others described in
ACM POPL 83).

     We will have an acceptable notation for algorithms when each algorithm
in Knuth's "Art of Computer Programming" is available in machineable form
and can be used without manual modification for most applications for which
the algorithm is applicable.  As an exercise for the reader, try writing
a few of Knuth's algorithms as Ada generics and make them available to 
others, and find out if they can use them without modifying the source
text of the generics.

     In practice, there now is a modest industry in reusable software
components; see the ads in any issue of Computer Language.  Worth noting
is that most of these components are in C.  

					John Nagle

dinucci@ogcvax.UUCP (David C. DiNucci) (07/06/87)

In article <titan.668> ijd@camcon.co.uk (Ian Dickinson) writes:
>> Xref: camcon comp.lang.ada:166 comp.lang.misc:164
>Hence a solution:  we somehow encode _abstractions_ of the ideas and place
>these in the library - in a form which also supplies some knowledge about the
>way that they should be used.  The corollary of this is that we need more
>sophisticated methods for using the specifications in the library.  
>(Semi)-automated transformations seem to be the answer to me.
>
>Thus we start out with a correct (or so assumed) specification,  apply
>correctness-preserving transormation operators,  and so end up with a correct
>implementation in our native tongue (Ada, Prolog etc, as you will).  The
>transformations can be interactively guided to fit the precise circumstance.
>[Credit]  I originally got this idea from my supervisor: Dr Colin Runciman
>@ University of York.

In his Phd thesis defense here at Oregon Graduate Center, Dennis
Volpano presented his package that did basically this.  Though certainly
not of production quality, the system was able to take an abstraction
of a stack and, as a separate module, a description of a language and
data types within the language (in this case integer array and file,
if I remember correctly), and produce code which was an instantiation
of the abstraction - a stack implemented as an array or as a file.

I haven't actually read Dennis' thesis, so I don't know what the
limitations of constraints on his approach are.  I believe he is
currently employed in Texas at MCC.
---
Dave DiNucci        dinucci@Oregon-Grad