Docsity
Docsity

Prepare for your exams
Prepare for your exams

Study with the several resources on Docsity


Earn points to download
Earn points to download

Earn points by helping other students or get them with a premium plan


Guidelines and tips
Guidelines and tips

Abstraction's Impact on Modern Programming: Data Types & Specification Overview, Lecture notes of Programming Languages

The evolution of programming languages and their response to new ideas about handling complexity in programs. It focuses on the development of abstract data types and specification techniques, which extend the set of types available to a program and provide a formal way to specify the properties and operations of new data types. The document also discusses the importance of verifying the consistency of specifications and implementations.

Typology: Lecture notes

2021/2022

Uploaded on 09/12/2022

venice
venice 🇬🇧

4.7

(10)

216 documents

1 / 31

Toggle sidebar

This page cannot be seen from the preview

Don't miss anything!

bg1
CMU-CS-80-116
The
Impact
of
Abstraction
Concerns
on
Modern
Programming
Languages
Mary
Shaw
Computer
Science
Department
Carnegie
Mellon
University
Pittsburgh,
Pa.
April
1980
Abstract
The
major issues of
modern
software
are
its
size
and
complexity,
and
its major
problems
involve
finding
effective
techniques
and
tools
for organization
and
maintenance.
This paper
traces
the
important
ideas
of modern
programming
languages
to
their
roots
in
the
problems
and
languages
of
the
past
decade
and
shows how
these
modern
languages
respond
to
contemporary
problems
in
software development.
Modern
programming's
key
concept
for
controlling
complexity
is
abstraction
--
that
is.
selective
emphasis
on
detail;
new
developments
in
programming
languages
provide
ways
to
support
and
exploit
abstraction
techniques.
APPR~OVED
FN
PUCLIC
RELEASE
DI$M
IbUTION'
UNLIMITED
To
appear
in
Proceedings
of
the
IEE
in
September
1080.
This
research
was
sponsored
by
the
National
Science Foundation under
Grant
MCS77-03883
and
by
the Defense
Advanced Research
Projects
Agency
(DOD).
ARPA
Order
No.
3597.
monitored
by
the
Air
Force
Avionics Laboratory
Under
Contract
F33615-78-C-1551.
The
views
and
conclusions
contained
in
this
document
are
those
of
the
author
and
should
not
be
interpreted
as
representing
the
official
policies,
either
expressed or
implied,
of
the
National
Science
Foundation,
the
Defense
Advanced
Research
Projects
Agency,
or
the
US
Government.
pf3
pf4
pf5
pf8
pf9
pfa
pfd
pfe
pff
pf12
pf13
pf14
pf15
pf16
pf17
pf18
pf19
pf1a
pf1b
pf1c
pf1d
pf1e
pf1f

Partial preview of the text

Download Abstraction's Impact on Modern Programming: Data Types & Specification Overview and more Lecture notes Programming Languages in PDF only on Docsity!

CMU-CS-80-

The Impact of Abstraction Concerns

on Modern Programming Languages

Mary Shaw

Computer Science Department Carnegie Mellon University Pittsburgh, Pa. April 1980

Abstract

The major issues of modern software are its size and complexity, and its major problems involve finding effective techniques and tools for organization and maintenance. This paper traces the important ideas of modern programming languages to their roots in the problems and languages of the past decade and shows how these modern languages respond to contemporary problems in software development. Modern programming's key concept for controlling complexity is abstraction -- that is. selective emphasis on detail; new developments in programming languages provide ways to support and exploit abstraction techniques.

APPR~OVED FN^ PUCLIC^ RELEASE

DI$M IbUTION'^ UNLIMITED

To appear in Proceedings of the IEE in September 1080.

This research was sponsored by the National Science Foundation under Grant MCS77-03883 and by the Defense Advanced Research Projects Agency (DOD). ARPA Order No. 3597. monitored by the Air Force Avionics Laboratory Under Contract F33615-78-C-1551. The views and conclusions contained in this document are those of the author and should not be interpreted as representing the official policies, either expressed or implied, of the National Science Foundation, the Defense Advanced Research Projects Agency, or the US Government.

Table of Contents

Aeession For NTIS CP.&I DTIC TAT **U:** --------- SDi strut inn/ .- o Avamilabllity Codes

    1. Issues of Modern Software
    1. Historical Review of Abstraction Techniques
    • 2.1. Early Abstraction Techniques
    • 2.2. Extensible Languages
    • 2.3. Structured Programming
    • 2.4. Program Verification
    • 2.5. Abstract Data Types
    • 2.6. Interactions Between Abstraction and Specification Techniques
    1. Abstraction Facilities in Modern Programming Languages
      • 3.1. The New Ideas
      • 3.2. Language Support for Abstract Data Types
      • 3.3. Generic Definitions
    1. Practical Realizations
      • 4.1. A Small Example Program
      • 4.2. Pascal
      • 4.3. Ada
    1. Status and Potential
      • 5.1. How New Ideas Affect Programming
      • 5.2. Limitations of Current Abstraction Techniques
      • 5.3. Further Reading
    1. References
    • Figu re 4-1: Declarations for Fortran Version of Telephone List Program List of Figures
    • Figure 4-2: Code for Fortran Version of Telephone List Program
    • Figure 4-3: Declarations for Pascal Version of Telephone List Program
    • Figure 4-4: Code for Pascal Version of Telephone List Program
    • Figu re 4-5: Ada Package Definition for Employee Records
    • Figu re 4-6: Declarations for Ada Version of Telephone List Program
  • Figure 4-7: Code for Ada Version of Telephone List Program

is one in which information that is significant to the reader (i.e., the user) is^ emphasized^ while^ details that are immaterial or diversionary, at least for the moment, are suppressed.

What we call "abstraction" in programming systems corresponds closely to what is called "analytic modelling" in many other fields. It shares many of the same problems: deciding which characteristics of the system are^ important,^ what^ variability^ (i.e.,^ parameters)^ should^ be^ included,^ which^ descriptive formalism to use, how the model can be validated, and so on. As in many other fields, we often define hierarchies of models in which lower-level models provide more detailed explanations for the

phenomena that appear in higher-level models. Our models^ also^ share^ the^ property^ that^ the

description is sufficiently different from the underlying system to require explicit validation. We refer to the abstract description of a model as its specification and to the next lower-level model in the hierarchy as its implementation. The validation that the specification is consistent with the implementation is called verification. The abstractions we use for software tend to emphasize functional properties of the software, emphasizing what results are to be obtained and suppressing details about how this is to be achieved.

Many important techniques for program and language organization have been based on the principle of^ abstraction.^ These^ techniques^ have^ evolved^ in^ step not^ only with^ our understanding^ of programming issues. but also with our ability to use the abstractions as formal specifications of the systems they describe. In the 1960's, for example, the important developments in methodology and languages were centered around functions and procedures, which summarize a program segment in terms of a name and^ a^ parameter^ list.^ At^ that^ time,^ we^ only^ knew^ how^ to^ perform^ syntactic^ validity checks, and specification techniques reflected^ this:^ "specification"^ meant^ little^ more^ than^ "procedure header" until late in the decade. By^ the late^ 1970's.^ developments^ were^ centered^ on^ the^ design^ of data structures. specification techniques drew^ on^ quite^ sophisticated techniques^ of mathematical logic, and programming language^ semantics^ were^ well^ enough^ understood^ to^ permit^ formal verification that these programs and specifications were consistent. Programming languages and methodologies often develop in response to new ideas about how to cope with complexity in programs and systems of programs. As languages evolve to meet these ideas, we reshape our perceptions of the problems and solutions in response to the new experiences. Our sharpened perceptions in turn generate new ideas which feed the evolutionary cycle.^ This^ paper explores the routes by which these cyclic advances in methodology and specification have led to current concepts and principles^ of^ programming^ languages.

2.1. Early Abstraction Techniques Prior to the late 1960's, the set of programming topics regarded as important was dominated by the syntax of programming languages. translation techniques,^ and^ solutions^ to specific^ implementation

problems. Thus we saw many papers on solutions to specific problems such as parsing, storage allocation, and data representation. Procedures were well-understood, and libraries of procedures were set up. These libraries met with mixed success, often because the documentation (informal specification) was inadequate or because the parameterization of the procedures did not support the cases of interest. Basic data structures such as stacks and linked lists were just beginning to be understood, but they were sufficiently unfamiliar that it was difficult to separate the concepts from^ the particular implementations. Perhaps it was too early in the history of the field for generalization and synthesis to take place, but in any event abstraction played only a minor role.

Abstraction was first treated consciously as a program organization technique in the late 1960's. Earlier languages supported built-in data types including at least integers, real numbers, and arrays, and sometimes booleans, high-precision reals, etc. Data structures were first treated systematically in 1968 (the first edition of [431), and the notion that a programmer might define data types tailored to a particular problem first appeared in 1967 (e.g., 671). Although discussions of programming techniques date back to^ the^ beginning^ of^ the field, the^ notion^ that^ programming^ is^ an^ activity^ that should be studied and subjected to some sort of discipline dates to the NATO Software Engineering conferences of 1968 [53] and 1969 [7].

2.2. Extensible Languages The late 1960's also saw efforts to abstract from the built-in notations of programming languages in such a way that any programmer could add new notation and new data types to a base language. The objectives of the extensible language work included allowing individual programmers to extend the syntax of the programming language, to define new data structures, to add new operators (including infix operators as well as ordinary functions) for both old and new data structures, and to add new

coittrjl 'trlucturets to the baise language. This wogk on extenisibility (GO LfiOl OtI. iI pdrt 0CMaIse it

underestimated the difficulty of defining interesting extensions. The problems included difficulty with keeping independent extensions compatible when all of them modify the syntax^ of^ the^ base^ language, with organizing definitions so that related information was grouped in^ common^ locations,^ and^ with finding techniques for describing an extension accurately (other than by exhibiting the code for the extension). However. it left a legacy in its influence on the abstract data types and generic definitions of the 1970's.

2.3. Structured Programming By the early 1970's. a^ methodology^ emerged^ for^ constructing^ programs^ by^ progressing^ from^ a statement of the objective through successively more precise intermediate stages to final code 1711

1171. Called "stepwise refinement" or "top-down programming", this methodology involves approaching a problem by writing a program that is free to assume the existence^ of^ any^ data

.......... mIlm i! =i. r-- iI ===m= meme

"ideal" control constructs a few years later [17] [35]. Although true consensus on this set of constructs has still not^ been^ achieved,^ the^ question^ is^ no^ longer^ regarded^ as^ an^ issue.

2.4. Program Verification In parallel with the development of "ideal" control constructs -- in fact, as part of their motivation -- computer scientists became interested in finding^ ways^ to make^ precise, mathematically manipulatable statements about what a program computes. The ability to make such statements is essential to the development of techniques for reasoning about programs, particularly for techniques that rely on abstract specifications of effects. New teclhiques were required because procedure headers, even accompanied by prose commentary, provide^ inadequate^ information^ for^ reasoning^ precisely^ about programs, and imprecise statements lead to ambiguities about responsibilities and inadequate separation of modules.

The notion that it is possible to make formal statements about values of variables (a set of values for the variables of a program is called the program state) and to reason rigorously about the effect of executing a statement on the program's state first appeared in the late 1960's [191 [321. The^ formal statements are expressed as formulas in the predicate calculus, such as y>x r, (x>0 z = X2). A programming language is described by a set of rules that define the effect each statement has on the logical formula that describes the program state. The rules for the language are applied to the assertions in the program in order to obtain theorems whose proofs assure that the program matches the specification.' By the early 1970's the basic concepts of verifying assertions about simple programs and describing a language in such a way that this is possible were tinder control 1351 (481. When applied by hand, verification techniques tend to be error-prone. and formal specifications, like informal ones, are susceptible to errors of omission [201. In response to this problem, systems for performing the verification steps automatically have been developed [211. Verification requires converting a program annotated with logical assertions to logical theorems with the property that the program is correct if and only if the theorems are true. This conversion process, called verification condition generation, is well-understood, but considerable work remains to be done on the problem of proving those theorems.

When the emphasis in programming methodology shifted to using data structures as a basis for program organization. corresponding problems arose for specification and verification techniques.

The initial efforts addressed the question of what information is useful in a specification (551.

Subsequent attention concentrated on making those specifications more formal and dealing with the

IAsuvey of these ideas appears (^) in [471; inlroductions to the methods (^) appear in Chapter 3 of [491 and (^) Chnpler 5 of [751.

verification problems [33]. From this basis, work on verification for abstract data types proceeded as described (^) in Section 3.

2.5. Abstract Data Types In the 1970's we recognized the importance of organizing programs into modules in such a way that knowledge about^ implementation^ details^ was^ localized^ as^ much^ as^ possible.^ This^ led^ to^ language

support for data types 1341, for specifications that are organized using the^ same^ structure^ as^ data^ [28)

[44] [741 (^) , and for generic definitions [611. The language facilities are based on the class construct of

Simula 181 191, ideas about strategies for defining modules [5411561, and concerns over the impact of

locality on program organization [731. The corresponding specification techniques^ include^ strong typing and verification of assertions about functional correctness.

Over the past five years, most research activity in abstraction techniques has been focussed on the language and specification issues raised by these considerations; much of the work is identified with the concept of abstract data types. Like structured programming, the methodology of abstract data types emphasizes locality of related collections of information. In this case, attention^ is^ focussed^ on data rather than on control. and the strategy is to form modules consisting of a data structure and its associated operations. The objective is to treat these modules in the same way as ordinary types such as integers and reals are treated; this requires support for declarations, infix operators, specification of^ routine^ parameters,^ and so^ on.^ The^ result,^ called^ an^ abstract^ data^ type,^ effectively extends the set of types available^ to^ a^ program^ --^ it^ explains^ the^ properties^ of^ a^ new^ group^ of^ variables by specifying the values one of these variables may have, and it explains the operations that will be permitted on the variables of the^ new^ type^ by^ giving^ the^ effects^ these^ operations^ have^ on^ the^ values^ of the variables. In a data type abstraction, we specify the functional properties of a data structure and its operations. then we implement^ them^ in^ terms^ of^ existing^ language^ constructs^ (and^ other data^ types) and show that the specification is accurate. When we subsequently use the abstraction, we deal with the new type solely in terms of its specification. (This techmiqu. Iil", ,i. l d(I htiel in ';, cli oll 3.) This philosophy was developed in several recent^ language^ research^ and^ development^ projects,

including Ada 1371, Alphard [741, CLU [461, Concurrent Pascal [41, Euclid [441. Gypsy [1]. Mesa [221,

and Modula [72]. The specification techniques used for abstract data types evolved from the predicates used in simple sequential programs. Additional expressive power was incorporated to deal with the way information is packaged into modules and with the problem of abstracting from an implementation to a data type [291. One class of specification techniques draws on the similarity between a data type and the mathematical structure called an algebra [281 [45]. Another class of techniq',ies explicitly

Impact of Abstractic:, Concerns on Modern Programming Languages 8

The history of programming languages shows a balance between language ideas and formal .echniques; in each methodology, the properties we specify are matched to our current ability to validate (verify) the consistency of a specification and its implementation. Thus, since we can rely on formal specifications (^) only to the extent that we are certain that they match their implementations, the development of abstraction techniques, specification techniques, and methods of verifying the consistency of a specification and an implementation must surely proceed hand in hand. In the future, we should expect to see more diversity in the programs that are used as a basis for modularization; we should also expect to see specifications that are concerned with (^) aspects of programs other than the purely functional properties we now consider.

3. Abstraction Facilities in Modern Programming Languages

With the historical background of Section 2, we now turn to the abstraction methodologies and .sp~rilication techniques that are currently under development in the programming language research community. Some of the ideas are well enough worked out to be ready for transfer to practical languages. but others are still under development.

Although the ideas behind modern abstraction techniques can be explored independently of programming languages, the instantiation of these ideas in actual languages is also important. Programming (^) languages are our primary notational vehicle for expressing a class of very complex ideas: the concepts we must deal with include not only the functional relations of mathematics, but also constructs that deal with relations over time. such as sequentiality and synchronization. Language designs influence the ways we think about algorithms by making some program structures easier to describe than others. In addition, programming languages are used for conmmunication among people as well as for controlling (^) machines. This role is particularly important in long-lived programs, because a program is in many ways the most practical medium for expressing the structure imposed by the designer -- and for maintaining the accuracy of this documentation over time. Thus, even though most programming languages technically have the same expressive power. differences among languages can significantly affect their practical utility.

3.1. The New Ideas Current activity in programming languages is driven by three sets of global concerns: simplicity of design, the potential for applying precise analytic techniques to formal specifications, and the need to control costs over the entire lifetime of a long-lived program.

Simplicity has emerged as a major criterion for evaluating programming language designs. We see a certain tension between the need for "just the right construct" for a task and the (^) need for a language small enough to understand thoroughly. This is an example of a tradeoff between

specialization and generality: if highly specialized constructs are provided, individual programs will be smaller, but at the expense of complexity (and feature-by-feature interactions) in the system as^ a whole. The current trend is to provide a relatively small base language that provides facilities for defining special facilities in a regular way [65]. An emphasis on simplicity underlies a number of design criteria that are now commonly used. When programs are organized to localize information, for example, assumptions^ shared^ among program^ parts^ and^ module^ interfaces^ can^ be^ significantly simplified. The introduction of support for abstract data types in programming languages allowb programmers to design special-purpose structures and deal with them in a simple way; it does so by providing a ri-finition facility that allows the extensions to be made in a regular, predictable fashion. The regularity introduced by using these facilities can substantially reduce maintenance problems^ by making it easier for a programmer who is unfamiliar with the code to understand tile assumptions about the program state that^ are^ made^ at^ a^ given^ point^ in^ the^ program --^ thereby^ increasing^ the^ odds that he or she can make a change without introducing new errors.

Our understanding of^ the^ principles^ underlying^ programming^ languages^ has^ improved^ to^ the point that formal and quantitative techniques are both feasible and useful. Current methods for specifying properties of abstract data types and^ for verifying^ that^ those^ specifications^ are^ consistent^ with^ the implementation are discussed in Section 3.2. Critical studies of testing methods are being performed 1361, and^ interest^ in^ quantitative^ methods^ for^ evaluating programs^ is^ increasing^ [581.^ It^ is^ interesting to note that there seems to be a strong correlation between the ease with which proof rules for language constructs can^ be^ written^ and^ the^ ease^ with^ which^ programmers^ can^ use^ those^ constructs correctly and understand programs that use them. The 1970's mark the beginning of^ a^ real^ appreciation^ that the^ cost^ of^ software^ includes^ the^ costs over the lifetime of the program, not just the costs of initial development or of execution. For large, long-lived programs. the cost of enhancement and maintenance usually dominate design, development, and execution costs. often by large factors. Two classes of issues arise (151. First. in order to modify a program successfully, a programmer must be able to determine what other portions of the program depend on the section about to be modified. The problem of making this determination is^ simplified^ if^ the^ information^ is^ localized^ and^ if^ the^ design^ structure^ is^ retained^ in^ the structure of the program. Off-line design notes or other documents are not an adequate substitute except in the unlikely case that they are meticulously (and correctly) updated. Second, large programs rarely exist in only one version. The majcr issues concerning the control of large-scale program development are problems of management. not of programming. Nevertheless, language-related tools can significantly ease the problems. Tools are becoming available for managing the interactions among many versions of a program.

simply managerial exhortations about program organization. Suitable^ language^ support^ requires solutions to a number of technical issues involving both^ design^ and^ implementation.^ These^ include:

- Naming: Scope rules^ are^ required^ to^ ensure^ the^ appropriate^ visibility^ of^ names.^ In addition, protection mechanisms [41] [521 should be considered in order to^ guarantee that hidden information remains private. Further. programmers must be prevented from naming the same data in more than one way ("aliasing") if current verification technology is to be relied upon. - Iype checking: It is necessary to check actual parameters^ to^ routines,^ preferably during compilation, to be sure they will be acceptable^ to^ the^ routines.^ The^ problem^ is^ more complex than^ the^ type^ checking^ problem^ for^ conventional^ languages^ because^ new^ types may be added during the compilation process and the parameterization of types requires subtle decisions in the definition^ of^ a^ useful type^ checking^ rule. - Specification notation: The formal specifications^ of^ an^ abstract^ data type^ should convey all information needed by the programmer. This is not yet possible, but current progress is described below. As for any specification formalism, it is also necessary to develop a method for verifying that^ a^ specification^ is^ consistent^ with its^ implementation. - Distributed properties: In addition to providing operations that are called as routines or infix operators, abstract data types must often supply definitions to support type-specific interpretation of various constructs of^ the^ programming^ language.^ These^ constructs include storage allocation, loops that operate on the elements of a data structure without knowledge of the representation, and synchronization. Some^ of^ these^ have^ been explored, but many open questions remain^ [46116211651. - Separate compilation: Abstract data types introduce two new problems to^ the^ process^ of separate compilation. First, type^ checking^ should^ be^ done across^ compilation units^ as welt as within units. Second, generic definitions offer significant potential for optimization (or for inefficient implementation). Specification techniques^ for^ abstract^ data^ types^ are^ the^ topic^ of^ a^ number^ of^ current^ research projects. Techniques that have been proposed^ include^ informal^ but precise^ and^ stylized English^ [311, models that relate the new type to previously defined types [741, and algebraic^ axioms^ that^ specify new types independently of other types [271. Many problems remain. The emphasis to date has been on the specification of properties of the code; the correspondence of these specification to informally understood requirements is^ also^ important^ [111.^ Further,^ the work^ to^ date^ has^ concentrated^ almost exclusively on the functional properties of^ the^ definition^ without^ attending,^ for^ example,^ to^ the performance or^ reliability.

Not all the language^ developments^ include^ formal^ specifications^ as^ part^ of^ the^ code.^ For^ example, Alphard includes language constructs that associate a specification with the implementation of a module; Ada and Mesa expect interface^ definitions^ that^ contain^ at^ least^ enough^ information^ to support separate compilation. All^ the^ work.^ however,^ is^ based^ on^ the^ premise^ that^ the^ specification must include all information that should be available to a user of the abstract data type.^ When^ it^ has

been verified that the implementation performs in accordance with its public specification [331, the abstract specification may safely be used as the definitive source of information about how higher-level programs may correctly use the module. In one sense we build up "bigger" definitions out of "smaller" ones; but because a specification alone suffices for understanding, the new definition is in another sense no bigger than the pre-existing components. It is this regimentation of detail that gives the technique its power.

3.3. Generic Definitions A particularly rich kind of abstract data type definition allows one abstraction to take another abstraction (e.g., a data type) as a parameter. These generic definitions provide a dimension of modelling flexibility that conventionally-parameterized definitions lack. For example, consider the problem of defining data types for an application that uses (^) three kinds of unordered sets: sets of integers, sets of^ reals,^ and^ sets^ of^ a^ user-defined^ type^ for^ points^ in 3-dimensional space. One alternative would be to write a separate definition for each of these three types. However, that would involve a great deal of duplicated text, since both the specifications and the code will be very similar for all the definitions. In fact. the programs would probably differ only where specific references to the types of set elements are made, and the machine code would probably differ only where operations on set elements (such as the assignment used to store a new value into the data structure) are performed. The obvious drawbacks of this situation include duplicated code, redundant programming effort, and complicated maintenance (since bugs must be fixed and improvements must be made in all versions). Another alternative would be to separate the properties of unordered sets from the properties of their elements. This is possible because the definition of the sets relies on very few specific properties of the elements -- it probably assumes only that ordinary assignment and equality operations for the element type are defined. Under that assumption, it is possible to write a single definition, say type UnOrdeiredSet(T: type) is that can be used to declare sets with several (^) different types of elements, as in var Counters: UniOrdeiedSet( integer): T ineis: UnOr'deo'edSet( integer): Si ,es: Uin-OiderecSet( real); Places: UnOi-dei-,rSeL(Pu iintfn3Space): using a syntax appropriate to the language that supports the generic definition facility. The definition of UnOrderedSet would provide operations such as inset, t. T estmbei's i1), and so on; the declarations of the variables would instantiate versions of these operations for all relevant element

c Vectors that contain (^) Employee information c Name is in FmpNam (24 chars). Phone is in EmpFun (integer) c Salary in in FmpSal (real), Division is in EmpDiv (4 chars) integer EmpFon(1000), Fmnpfiv(1000) real FmpSal( 1000) double precision EmpNam(3,1000) c Vectors that contain Phone list information c Name is in DivNam (24 chars), Phone is in DivFon (integer) integer DivFon(1000) double precision DivNam(3.1000) C declarations of scalars used in program integer StafSz. DivSz, i, j intcger WhichO double precision q

Figure 4-3: Declarations for Pascal Version of Telephone List Program

whose division (Fmpf i v ( i)) matches the division desired (Wit i chD). When a match is found, the

name and phone number of the employee are added to the telephone list. Second, the telephone list is sorted using^ an^ insertion^ sort.^3

There are several important things to notice about this program. First. the data about employees is stored in four arrays, and the relation among these arrays is shown only by the similar naming and the comment with their declarations. Second, the character string for each employee's name must be handled in eight-character segments, and there is no clear indication in either the declarations or the code that character strings are involved. 4 The six-line test that determines whether DivNam(* .i)<DivNam(.j) could be reduced to three tests if it were changed (^) to a test for less-than-or-equal, but this would make the sort unstable. Third, all the data about employees, including salaries, is easily accessible and modifiable; this is undesirable from an administrative standpoint.

4.2. Pascal Pascal [40] is a simple algebraic language that was designed with three primary objectives. It was to support modern programming development methodology; it was to be a simple enough language to teach to students; and it was to be easy to implement reliably, even on small computers. It has, in

(^3) This selection is nota ( eloosement of insertion sorting in general. Howevei. most readets will tecognize (^) the algorithm. and the topic of this pnpew is the evoltion of poogramnisig languages, not sorting techniques. 41n(dee. the implemenlatlims (^) of floating point in some versions of Fortran (^) intesere with this type violation. (^) Character strings ar' dealt with mote ap. owttintely in the Fo, tonn7l standard.

Impact of Abstraction Concerns on Modem Programming Languages 15

c Get data for division WhichD only DivSz = 0 do 200 i = 1,StafSz if (FmpDiv(i) .ne. WhichD) go to 200

DivSz = DivSz + I

DivNam(1.DivSz) (^) = FinpNam(l,i-) DivNai(2.DivSz) = FinpNain(2.i) D ivNan(3.DivS7) = FmpNain(3,i) DivFon(DivSz) = FmpFon(i) 200 continue c Sort telephone 1ist if (DivSz (^) .eq. 0) go to 210 do 220 i = t.DivSz

do 230 j = i+t,DivSz

if (DivNan(l1.i) (^) .gt. DivNam(tj)) go to 240 if (DivNam(t,i) .lt. DivNajn(1,j)) go to 230 if (DivNam(2,i) .gt. DivNain(2.j)) (^) go to 240 if (^) (DivNain(2.i) .lt. DivNnmi(2.j)) go to 230 if (DivNain(3,i) .gt. DivNam(3.j)) go to 240 go to 230 240 do 250 k = 1. q = DivNain(k.i) DivNam(ki) = Divnain(kj) 250 DivNain(k.j) = q k = DivFon(i) DivFon(i) (^) = DivFon(j)

DivFon(j) = k

230 continue 220 continue 210 continue

Figure 4-2: Code for Fortran Version of Telephone List Program

general. succeeded in all three respects.

Pascal provides (^) a number of.facilities for supporting structured programming. It provides the standard control constructs of structured programming, and a formal definition [351 facilitates verification of Pascal programs. It supports (^) a set of data organization constructs that are suitable for defining (^) abstractions. These include the ability to define a list of arbitrary constants as an enumerated lype, the ability to define heterogeneous (^) records with individually named fields, data types that can be dynamically allocated and referred to by (^) pointers, and the ability to name a data structure as a type (though not to bundle up the data structure with a set of operations).

The (^) language has become quite widely used. In addition to serving as a teaching language for

individual fragments of a name. (^) The difference between the complexity of the code in Figures 4-2 and 4-4 may (^) not seem large, but when it is compounded over many individual composite structures with different representations, the difference can be large indeed. If Pascal allowed programmer-defined types to accept parameters, a single definition of strings that took the string length as a parameter could replace S tri ng and Shor tS t r i ng; Ada does allow this, and the change is made in the Ada program of Section 4.3.

( Get data For division WhicliDiv only }

DivSiue := 0;

for i := I to Staff'Size (^) do if Staff[i].Division = WhichDiv then begin DivSize := DivSize + 1; Phones[DivSize].Name := Staff[i].Name; Phones[DivSie].Plione := Staff[i].Phone; end;

( Sort telephone list }

for i := (^) 1 to DivSize do for j := i+l to DivSize do if Phones[i].Name > Phones[j].Name then begin q := Phones[i]; Phones[i] Phones[j]; Pliones[j] q; end;

Figu re 4-6: Declarations for Ada Version of Telephone List Program

The type definitions for FimpRec and PhoneRec abstract from specific data (^) items to the notions "record of information about an employee" and "record of information (^) for a telephone list". Both the employee data base and the telephone (^) list can thus be represented as vectors whose elements are records of the appropriate types.

The declarations of S t a f f and Phones have the effect of indicating (^) that all the components are related to the same information structure. In addition, the definition is organized as a collection of records, one for each employee -- so the primary organization of the data structure is by employee. On the other hand. the data organization (^) of the Fortran program was dominated by the arrays that correspond (^) to the fields, and the employees were secondary.

Just as in the Fortran program. the telephone list is constructed in two stages (Figure 4-4). Note that Pascal's (^) ability to operate on strings and records as single units has substantially simplified the

manipulation of names and the interchange step of the sort.^ Another^ notable^ difference^ between^ the two programs is in the use of conditional statements.^ In^ the Pascal^ program,^ the^ use^ of^ if^ ...^ then statements emphasizes^ the^ conditions^ that^ will^ cause^ the^ bodies^ of^ the^ if^ statements^ to^ be^ executed. The Fortran if statements with go to's, however, describe conditions in which code is not to be executed, leaving the reader of the program to compute the conditions that actually correspond to the actions.

It is also worth mentioning that the Pascal program^ will^ not^ execute^ the body^ of^ the^ sort loop^ at^ all if no employees work in division Wh i chl i v (that is, if D ivSi7e is 0). The body of the corresponding Fortran loop would be executed once in that situation if the loop had not been protected by an explicit test for an empty list. While it would do no harm to execute this particular loop once on an empty list, in general it is necessary to guard Fortran loops against the possibility that the upper bound is less than the lower bound.

4.3. Ada The Ada language is currently being developed under the auspices of the Department of Defense in an attempt to reduce the software costs of embedded computer^ systems.^ The^ project includes components for^ both^ a^ language^ and^ a^ programming^ support^ environment.^ The^ specific^ objectives^ of the Ada development include significantly reducing the number of^ programming^ languages^ that^ must be learned, supported, and maintained within the Department of^ Defense.^ The^ language^ design emphasized the goals of high program reliability, low maintenance costs, support for^ modern programming methodology, and efficiency of compilers and object programs [371 [38).

The language developed through competitive designs constrained^ by^ a^ set^ of^ requirements^ [^ 13].^ It is undergoing final revisions and will be frozen in mid-1980. Development of^ the^ programming environment will continue over the next two years [14]. Since compilers for^ the^ language^ are^ not^ yet available, it is too soon to evaluate how well the language meets its goals. However. it is possible^ to describe the way various features of the language are intended to respond to the abstraction issues raised here. Although Ada grew out of the Pascal language philosophy, extensive syntactic changes and semantic extensions make it a very different language from Pascal. The major additions include module structures and interface specifications to large-program organizations and separate compilation, encapsulation facilities and generic definitions to support abstract data types, support for parallel processing. and control over low-level implementalion issues related to the architecture of object machines. There are three major abstraction tools in Ada. The package is used for encapsulating a set of