The Impact of Software Engineering
Research on Modern Progamming
Languages
BARBARA G. RYDER
Rutgers University
MARY LOU SOFFA
University of Virginia
and
MARGARET BURNETT
Oregon State University
Software engineering research and programming language design have enjoyed a symbiotic relationship, with traceable impacts since the 1970s, when these areas were first distinguished from
one another. This report documents this relationship by focusing on several major features of current programming languages: data and procedural abstraction, types, concurrency, exceptions, and
visual programming mechanisms. The influences are determined by tracing references in publications in both fields, obtaining oral histories from language designers delineating influences on
them, and tracking cotemporal research trends and ideas as demonstrated by workshop topics,
special issue publications, and invited talks in the two fields. In some cases there is conclusive
This article has been developed under the auspices of the Impact Project. The aim of the project
is to provide a scholarly study of the impact that software engineering research—both academic
and industrial—has had upon practice. The principal output of the project is a series of individual
papers covering the impact upon practice of research in several selected major areas of software
engineering. Each of these papers is being published in ACM TOSEM. Additional information about
the project can be found at http://www.acm.org/sigsoft/impact/.
This article is based upon work supported by the U.S. National Science Foundation (NSF) under
award number CCF-0137766, the Association of Computing Machinery Special Interest Group
on Software Engineering (ACM SIGSOFT), the Institution of Electrical Engineers (IEE), and the
Japan Electronics and Information Technology Association (JEITA). Any opinions, findings and
conclusions or recommendations, expressed in this publication are those of the authors and do not
necessarily reflect, of the NSF, ACM SIGSOFT, the IEE, or JEITA.
Authors’ addresses: B. G. Ryder, Division of Computer and Information Sciences, Rutgers University, 110 Frelinghuysen Road, Piscataway, NJ 08854-8019; email: ryder@cs.rutgers.edu; M. L.
Soffa, Department of Computer Science, School of Engineering and Applied Science, University of Virginia, 151 Engineer’s Way, P.O. Box 400740, Charlottesville, VA 22904-4740; email:
soffa@cs.virginia.edu; M. Burnett, School of Electrical Engineering and Computer Science, Oregon
State University, Corvallis, OR 97331-5501; email: burnett@cs.orst.edu.
Permission to make digital or hard copies of part or all of this work for personal or classroom use is
granted without fee provided that copies are not made or distributed for profit or direct commercial
advantage and that copies show this notice on the first page or initial screen of a display along
with the full citation. Copyrights for components of this work owned by others than ACM must be
honored. Abstracting with credit is permitted. To copy otherwise, to republish, to post on servers,
to redistribute to lists, or to use any component of this work in other works requires prior specific
permission and/or a fee. Permissions may be requested from Publications Dept., ACM, Inc., 1515
Broadway, New York, NY 10036 USA, fax: +1 (212) 869-0481, or permissions@acm.org.
C 2005 ACM 1049-331X/05/1000-0431 $5.00
ACM Transactions on Software Engineering and Methodology, Vol. 14, No. 4, October 2005, Pages 431–477.
432
•
B. G. Ryder et al.
data supporting influence. In other cases, there are circumstantial arguments (i.e., cotemporal
ideas) that indicate influence. Using this approach, this study provides evidence of the impact of
software engineering research on modern programming language design and documents the close
relationship between these two fields.
Categories and Subject Descriptors: D.2.0 [Software Engineering]: General; D.3.0 [Programming Languages]: General; D.3.3 [Programming Languages]: Language Constructs and Features; D.1.5 [Programming Techniques]: Object-oriented Programming; D.1.7 [Programming
Techniques]: Visual Programming
General Terms: Design, Languages, Reliability, Security
Additional Key Words and Phrases: Software Engineering, Programming Languages
1. INTRODUCTION
This article is part of the larger NSF-sponsored Impact project that is documenting the influence of software engineering research on software practice.
In this article, we focus on the impact of software engineering research on the
design of programming languages from a historical perspective. That is, the
article is not a survey of software engineering accomplishments, but instead
focuses on documenting software engineering research that has influenced the
design of programming languages. The influence was determined by examining
publications, oral reports, and the time sequence between significant advances
in software engineering and programming language design.
The production of software requires software engineering techniques, such
as specification, design, implementation, testing, and maintenance. Essential
to performing the last three phases of software development is the selection of
a programming language(s) as an implementation vehicle. The programming
language(s) chosen needs to offer the application programmer the power to
naturally express the task at hand in a disciplined manner. The requirements
of expressiveness and software engineering methodology, evolving over time,
clearly impact the design of programming language features.
Thousands of programming languages have been designed to address the
unique demands of application areas. Many have been developed purely for research exploration, while others have been targeted for production use. Some of
the languages are general purpose while others were developed for particular
domains. To name a few programming languages used in practice today, C++,
Java, Ada,1 Perl, Visual Basic, and COBOL all are widely-used across many
application domains. Software engineering and the design of programming languages enjoy a synergistic relationship, each influencing the other. This relationship holds with regard to both research and practice in these two fields.
The main goal of this report is to document how fundamental research in
software engineering has been a resource for programming language features
commonly used today. To achieve our goal, it is necessary to trace the ongoing
interrelations between software engineering research and programming language design. In examining these interrelationships, we have found symbiotic
1 We
use the term Ada to refer to Ada 83 in this article; we will use Ada 95 to refer to the later
version of the language.
ACM Transactions on Software Engineering and Methodology, Vol. 14, No. 4, October 2005.
The Impact of Software Engineering Research
•
433
interactions between these two fields that have both influenced and strengthened each other. Thus, in this report we track research both in programming
languages and software engineering.
In accomplishing this goal, there are a number of challenges that must be addressed. The synergy between software engineering research and programming
language design renders attribution of some specific contributions difficult. Initially, there was no distinction between the software engineering and programming languages research communities. Research in programming languages
design, specification, programming methodology, and software engineering was
being done by members of a single amorphous field. This field had the same conference publication venues until the late 1970s (e.g., IFIP Working Group 2.3
formed in 1969, NATO Software Engineering Conferences 1968, 1969). Initial
research contributions in both fields were essentially shared contributions to
this original, single software field. In the middle of the 1970s, this community
began to split into the fields of software engineering and programming languages. The first in the series of the ACM SIGACT/SIGPLAN Symposia on
Principles of Programming Languages (POPL) was held in 1973, while the first
IEEE/TCSE ACM/SIGSOFT International Conference on Software Engineering (ICSE) was held in 1975. These two conferences mark the beginning of the
differentiation between the two communities. As the fields began to evolve into
distinct communities, researchers who had published in the same conferences
and journals now began to publish in both software engineering and programming languages conferences, and thus, the classification of them as either a
software engineering or a programming languages researcher is difficult. Interestingly, these two communities have continued to grow further apart.
Another challenge is differentiating between the contributions of software
engineering research and software engineering practice, since both have influenced the design of programming languages. Questions to be considered include
the following: Was a feature of a programming language changed due to a new
research idea or due to the experiences of practicing software engineers? What
influenced the wide acceptance of object-oriented programming that current languages support? Does this show the influence of practitioners’ experiences or the
adoption of a new paradigm explored by researchers or both? Because of the
interrelatedness of languages, software engineering practice and software engineering research, these questions are difficult to answer.
Finding primary sources to document the influence of software engineering
research presents an additional challenge. Research publications are needed to
determine this impact; examination of the topics of meetings and workshops
held at specific times also yields some information as to software engineering
concerns. The oral and written history of how a programming language evolved
is also needed to complete this study. Often the communities feel that certain
concepts were in the air [Gabriel personal communication] in that everyone
agreed these were important ideas, but no one really knew where they originated, or who was instrumental in developing them.
Clearly, studying the evolution of the concepts and features of all programming languages that have been developed presents an intractable problem.
The challenge here is to select specific languages to study and their significant
ACM Transactions on Software Engineering and Methodology, Vol. 14, No. 4, October 2005.
434
•
B. G. Ryder et al.
features, to render the problem feasible. The existence of software process, language tools, and environments adds more complexity to the study because they
also have had influence on research and practice in both software engineering
and programming languages. Thus, we focused only on the software engineering
concepts that made their way into programming languages; we did not address
software process, tools, and environments.
The final challenge is the determination of an effective research methodology
for this study. One possible approach is to examine this question from a history
of science perspective; that is, focusing on practice at a given time and place,
asking why and how ideas originated and evolved. Our approach has been to
examine results of research as evidenced in published works and to infer influence from these results. We also have conducted interviews with programming
language designers that explore what they were thinking and how they were
being influenced at the time of accomplishing their designs.
This article discusses the impact of software engineering research on a selected set of widely used languages: Java, C++, Ada, and Visual Basic, and
some of their significant concepts. Concepts considered include abstractions,
visibility, reuse, exception handling, types, concurrency, and visual programming features. The research methodology used to study the historical interactions between software engineering research and programming language design takes into account the iterative evolution of programming languages and
the influence of software engineering research on this evolution.
The research methodology is described in Section 2. Section 3 traces the development of individual programming concepts. Section 4 recounts the development of visual programming and its relationship to Visual Basic and to software engineering research. Section 5 summarizes interviews conducted with
programming language designers, in which they were questioned about what
influenced their designs. Finally, Section 6 summarizes the findings.
2. RESEARCH METHODOLOGY
Given the focus of this study, several languages, selected because of their importance to current programming practice, were examined for the constructs
and the concepts they expressed.
Based on the constructs found in many languages, a number of languages
were considered as possible choices for the focus of this study. Neither COBOL
nor FORTRAN was selected because, although they remain in wide use today,
they are not used as general purpose programming languages. COBOL is, and
has been, used for business applications; FORTRAN is the language of choice for
scientific computation. Likewise, C is used mainly as a systems programming
language.
Ada, C++, and Java are widely used for general purpose applications. Visual
Basic is a language widely used for fast prototyping, relying primarily on Basic
plus graphical interfaces to leverage programmer productivity. We included
Visual Basic in its own section of the report as a representative of visual programming in practice and because of its widespread use. Thus, the focus of this
study centers on general purpose languages: Ada, C++, Java, and Visual Basic.
ACM Transactions on Software Engineering and Methodology, Vol. 14, No. 4, October 2005.
The Impact of Software Engineering Research
•
435
This language selection is not an attempt to be definitive about current practice, nor does it represent a value judgment about the importance of languages
in specific application areas. These language choices have many of the features
expected in today’s general purpose languages and also enable the tracing of
historical software engineering influences.
2.1 Software Maturation Models
In 1985, Redwine and Riddle [1985] presented a maturation model of software
technology, which discusses the steps for transition from a research concept
to practice. The goal of the work was to discover the process, principles, and
techniques useful in transitioning modern software to widespread use. They
identified six major phases.
— Basic research: investigate ideas and concepts that eventually evolve into
fundamentals and identify the critical problems and subproblems.
— Concept formulation: key idea or problem is identified and the ideas are
informally circulated, convergence of a set of ideas, and publications start to
appear that suggest solutions to subproblems.
— Development and extension: present a clear definition of a solution in
either a seminal paper or a demonstration; preliminary use of the technology;
generalize the approach.
— Internal enhancement and exploration: extend approach to another
domain, use technology to solve real problems; stabilize and port technology;
development of training materials.
— External enhancement and exploration: similar to previous phase but
performed by a broader group, including outside the development group.
— Popularization: show substantial evidence of value and applicability; develop production-quality version, commercialize and market.
In a keynote address at ICSE 2001, Shaw [2001] used this model to describe
the coming of age of software architecture. The first phase, the basic research
phase, involved the exploration of the advantages of specialized software structure for software process. This phase also cataloged systems to identify common
software architectural styles, leading to models for explaining architectural
styles. In the concept formulation phase, architecture description languages
were developed and architectures were classified. In the development and extension phase, languages were extended and new languages developed, as the
concepts were refined. Meetings, journals and conferences that were devoted
solely to software architecture were seen. In the next phase, formal analysis
of real systems was performed. In the external enhancement and exploration
phase, Unified Modeling Language TM (UML) was developed, as an example.
Finally, in the popularization phase, standards were developed, demonstrating
that software architecture is accepted and used in software engineering.
We developed a similar maturation model for programming language design
and software engineering and used this model to determine the interactions of
programming languages and software engineering. Our model has five phases
ACM Transactions on Software Engineering and Methodology, Vol. 14, No. 4, October 2005.
436
•
B. G. Ryder et al.
followed by iterative refinement using the last two phases. They are:
— Basic research: identify a software engineering problem and explore basic
ideas and concepts.
— Concept formulation: circulate ideas informally to develop a research community and publish solutions to the problem or subproblems.
— Introduce into a programming language: frame a solution to the problem
in a programming language, which is used for a period of time.
— Refinement: as a result of using the language feature as well as exploring
other facets of the problem, solutions are refined and extended.
— Extend the programming language or develop a new one: based on the
refinements, an existing language is either changed or a new one is developed.
The last two phases are repeated until software engineers and programming
language designers find an acceptable solution.
2.2 Methodology and Resources Used
To provide focus, we used the model to explore concepts in object-oriented
and imperative languages that are commonly used; that is, we examined modern programming languages and identified a set of core features, as was done
in Shaw et al. [1978]. We used these core features to demonstrate the relation
between software engineering research and programming languages.
An extensive survey was performed in both the software engineering and
programming language research literature to find references to the constructs
and concepts. Historical papers describing the evolution of particular programming languages were also examined. Key to the approach was, for each concept,
performing a reverse chronological search through the materials gathered to
look for interactions, both cited and implied,2 between software engineering
research and programming language design. Of greatest interest were the origin, development, and evolution of these concepts to their current form. The
papers found through this search were then read for evidence of influence on
programming language design. We used time lines to help determine the interrelationships between the fields and their potential impact on one another. In
many cases, we used the date that an article was published as an indication of
possible influence.
We also conducted interviews with language designers to acquire firsthand
historical information. With the help of Mike Mahoney, History of Science Professor at Princeton University, we developed a set of five questions and emailed
the questions to the language designers. We gave them the option of answering
the questions by email or by phone. In some cases, we had further contact. A
section summarizing the responses appears in this article in Section 5. The language designers participating in the interviews were Professor Niklaus Wirth
(Pascal, Modula), Professor Boris Magnusson (Simula), Dr. Bjarne Stroustrup
2 As an example of an implied interaction, we may infer a relation between the temporal precedence
of a published software engineering result and the subsequent appearance of a seemingly related
programming language construct.
ACM Transactions on Software Engineering and Methodology, Vol. 14, No. 4, October 2005.
The Impact of Software Engineering Research
•
437
(C++), Dr. Jean Ichbiah (Ada), Tucker Taft (Ada 95), Tim Lindholm (Java) and
Dennis Canady (Visual Basic).
The resources used included both journal and conference papers in software engineering and programming languages. These written documents were
acquired through the usual digital and hard copy library sources as well as
through personal communication. In addition, we used first person interviews
that were published in various venues. With the development of later languages
came rationales about why language features and their forms were included;
these provided another resource. Last, because many of the ideas that impacted
software engineering and programming languages were in the air, we used the
results of the interviews that we conducted for insight and further references.
We also used the existence of workshops and conferences in different time periods to indicate significant issues being considered by researchers.
In the next section, we apply this technique to several language features as
they evolved to their usage in Java, C++, and Ada. These include control and
data abstractions, inheritance, types, exception handling, and concurrency.
3. LANGUAGE FEATURES
In tracing the interaction between software engineering and programming languages, we begin with the design of abstractions, including control, procedural,
and data, which demonstrate a clear symbiotic relationship between research
in the programming language design and software engineering communities,
to the benefit of software practice.
3.1 Abstraction
With the development of increasingly more complex applications, abstraction
has become a critical mechanism to control complexity in software. Thus, it
is a major part of programming language design and software engineering
methodology, necessitating interaction between the two communities. Modern
programming languages support abstraction by enabling the user to express
what is significant and suppress what is not [Shaw 1984]. There are basically
three types of abstractions used when constructing software, namely, data, control, and procedural abstractions. Most widely used programming languages
today include a number of different constructs to support these various forms
of abstractions. The abstraction mechanisms in languages have been affected
by past experiences in software engineering research and practice.
3.1.1 Control Abstraction. Control abstraction describes a well defined
operation that expresses the execution sequence of statements (actions) in a
program and includes intraprocedural control structures such as if-then-else,
while, and switch statements. Typically all languages have built-in control abstraction. During the 1960s, indiscriminate transfer of control was believed to
cause difficulties and errors in writing and understanding programs. In the late
1960s and early 1970s, two important software design methodologies emerged
that stressed the importance of properly organizing and structuring programs.
One method, called stepwise refinement or top-down design, initially created an
ACM Transactions on Software Engineering and Methodology, Vol. 14, No. 4, October 2005.
438
•
B. G. Ryder et al.
abstraction of the program without details about the data structures or operations [Wirth 1971a]. With each step, the program is successively refined until
the final code is constructed. Thus there is a separation between the abstract
definition of structures, and procedures and their implementation.
About that same time, there was a debate about the harmful effects of go to
statements [Dijkstra 1968b; Rubin 1987]. Intertwined with the discussion of
go tos was the structured programming movement [Dijkstra 1969; Dahl et al.
1972]. Consequently, the languages developed after the 1970s had structured
control constructs and deemphasized or eliminated go to statements. However,
there were a few cases where escaping from statements was felt to be necessary [Hopkins 1972], and languages have either included a go to or put in other
constructs that enabled a break out of a statement, including breaking out of
loops and case statements.
Both top-down design and structured programming are mechanisms to make
software simpler, more understandable, and easier to modify. They enable abstractions to be specified and then implemented. Control flow patterns in a
program are instrumental in developing and understanding a program. From
the software engineering research on structured programming and top-down
design, control structures with a single entry point and a single exit point
made programs more understandable. This led to a set of accepted intraprocedural control constructs [Shaw 1984]. All commonly used languages feature
the single-entry, single-exit (almost) design in their control structures.
Another example of programming methodology influencing programming
language design comes from generators in Alphard which became instantiated
as iterators in CLU. These structures expressed the concept of iterating through
a set of elements or objects [Shaw et al. 1977; Liskov et al. 1977]. The idea was
to separate the abstraction of the concept of iteration from the implementation. This idea is found in object-oriented languages, which have the concept of
iterating through a collection of objects.
Thus, the research of the early combined software community on developing,
understanding, and modifying programs influenced the design of structured
programming language constructs.
3.1.2 Procedural Abstraction. Procedural abstraction deals with organizing and decomposing a program into modules that typically have specific purposes. Procedural abstraction involves the definition of an interface and an implementation of the unit. Units were composed of local data and code that was
able to access nonlocal data as well as local data. FORTRAN introduced procedural abstraction through its subroutine and function program units. These
could be developed independently of the programs that call them and could be
separately compiled. Simula 67 also had procedural abstraction through the
class structure with functions. Neither FORTRAN or Simula 67 had any separation between the interface and the implementation, nor were the types in
the interface checked when used.
In 1971, Parnas wrote a most influential paper that formally introduced the
importance of modularity. The paper describes a method and need for decomposing a program into modules [Parnas 1971, 1972]. The idea of information
ACM Transactions on Software Engineering and Methodology, Vol. 14, No. 4, October 2005.
The Impact of Software Engineering Research
•
439
hiding was also introduced in this paper by showing that the main benefit of
hiding implementation was to allow changes to the implementation to be confined to its module. Parnas characterized a module by its knowledge of a design
decision, which is hidden from all other modules. For example, in the paper a
symbol table implementation was visible to its module but invisible to the rest
of the system. The publication of this seminal paper represented a transition
from software engineering research to concept formulation to programming language design. The module structures that were eventually developed by others
differed in how the interface and implementation were managed, whether the
interfaces were type checked, and the visibility rules for accessing the entities
of a module.
A module enables more structure than a procedure. Modules allow programmers to group related items together, including types, data, and routines.
Modula-2 was one of the first languages that allowed the separation of the interface from the body of a module [Wirth 1977]. In Modula-2, the interface and
body can be separate in the same file or even appear in different source files.
In the mid-eighties, modules were refined to software components to enable
reuse. Software reuse was seen as possibly “increasing software productivity
by an order of magnitude or more” by Horowitz and Munson [1984]. Their
notion of software reusability was broad, including not only code reuse, but
also the reuse of software design. In their discussion of reusable code, they
cite McIlroy’s article from the 1968 NATO conference that described factories
for building software components [McIlroy 1976]. At the time, this idea was
considered impossible to achieve because of a lack of tools to create, index,
search and compose components efficiently; also, the ability to describe the semantics of a component to a user so that the user could assess its utility to
the task at hand was limited. After reviewing several approaches that offered
software reuse through high-level systems that produce programs from specifications and user-supplied parameters, Horowitz and Munson praised Ada as
a language with features to support software reuse, including the Ada package
(i.e., an abstract data type) and the generic procedure [Horowitz and Munson
1984]. Thus, Horowitz and Munson believed that the programming language
design community was providing tools to accomplish the software engineering
research goal of software reuse. The designs of Ada and the research language
CLU, both demonstrated an emphasis on modularity and the ability to reuse
code. CLU was intended for programming in the large, emphasizing program
readability and understandability over ease of writing [Liskov 1993]. Liskov
believed that it was possible to develop a programming methodology through
designing a programming language so that problem solutions were similar to
programs in that language. This principle guided the design of CLU, which
emphasized data abstraction and encapsulation as well as reliability using exceptions. Liskov stated that a driving force behind her language design was
the desire to write correct programs, using language constructs to either help
avoid errors or help find them automatically. She described many design decisions in terms of a goal of program safety, including the decision on compiletime type checking within a module (and bounds type checking for arrays)
[Liskov 1993].
ACM Transactions on Software Engineering and Methodology, Vol. 14, No. 4, October 2005.
440
•
B. G. Ryder et al.
Ada was one of the first widely used languages to feature separation of specification and implementation as part of the language design, which enabled
separate compilation of modules, and still provided checking of the interfaces.
Ada was designed specifically “to support development of large programs composed of reusable software components” [Wegner 1984]. Ada separated the interface and implementation through its package module [DOD 1980]. An Ada
package can contain procedures, functions, types and variables. The specification of a package is through its interface, which is declared separately from its
implementation.
An important component of the module concept is the visibility rules for
the interface and implementation. The early languages (e.g., Pascal, Algol 60)
used textual scope to define the interfaces between modules (e.g., subroutines,
procedures). Wulf and Shaw detailed the problems with using scope for interfaces. They enumerated some desirable properties of an interface, including
(1) the scope of a name should not automatically be extended to inner blocks,
(2) access rights to a structure and its substructures should be decoupled, and
(3) it should be possible to distinguish different types of access [Wulf and Shaw
1973]. As mentioned previously, Modula-2 [Wirth 1971a] contains the idea of
separating the interface and implementation; the implementation is not visible to users. However, there is no way to hide entities in the interface. The
package specification in Ada does enable parts of the interface to be hidden,
as well as the implementation. Ada packages also allow information to be left
out of the declaration and provided in a separate file not visible to users of the
abstraction [DOD 1980]. However, Ada allows the header of a package to be
divided into public and private parts. In Ada, data types expose the type name
and operations allowed on the type. The data structures used and the implementation of operators are not visible to users. Thus, the ideas of information
hiding were eventually implemented in programming languages by controlling
access through the interface, including the introduction of access rights such
as private, public, and protected. The access rights grew out of data abstraction
research, which is discussed in the following section.
3.1.3 Data Abstraction. The concept of data abstraction, or abstract data
type, has had a profound influence on both software development and programming language design. The major thrust of programming languages and software engineering research activity in the 1970s was to explore issues related
to data abstraction and visibility control [Ghezzi and Jazayeri 1998].
Abstract data types give programmers the capability of safely defining their
own types. Modern day concepts of abstract data types include (1) encapsulating
or enclosing data and the related operations on the data, (2) naming the data
type, (3) placing restrictions on the use of the operators, (4) having rules that
specify the visibility of the data, and (5) separating the specification from the
implementation.
The notion of data abstraction was first introduced in the Simula 67 language
by associating abstract operations with the entities for which they were defined
[Dahl and Nygaard 1967; Birtwistle 1973]. The entities and operations were
encapsulated in a class structure. However, accessing the data entities in a class
ACM Transactions on Software Engineering and Methodology, Vol. 14, No. 4, October 2005.
The Impact of Software Engineering Research
•
441
was not restricted to the class operations. It should be noted that the creators of
Simula 67 did not think about restricting the use of class entities [Rowe 1980].
The idea of a class in Simula 67 paved the way for the later development of data
abstraction, classes and object-oriented programming. For various reasons, including, (1) the price of the compiler, (2) the perception that Simula 67 was a
simulation language, and (3) the lack of resources to publicize it [Nygaard and
Dahl 1978], Simula 67 did not receive the attention it rightly deserved until
much later. Finally, in 2001, Ole-Johan Dahl and Kristen Nygaard, the developers of Simula 67, received the Turing award for ideas fundamental to the
emergence of object-oriented programming, through their design of Simula 67.
Unfortunately, they both died in the same year and were not able to personally
receive the award.
The idea of using abstract data types as an abstraction technique for reliable
software design was presented by Liskov [1972]. In this paper, Liskov describes
various types of abstractions that provide the infrastructure to produce reliable
software that is easier to prove and/or test. One of the ideas presented was to
develop an abstraction based on the use and structure of data and limiting
the visibility of functions in the abstraction to what they need to know. Thus
information hiding was also included as part of abstraction concept. The data
for the functions constituted the resources of the abstraction.
In the 1970s, the software engineering community recognized the need to
organize programs into modules by localizing implementation details as much
as possible. This led to the development of language support for abstract data
types. The first research to incorporate data abstraction into a language was
CLU, through its cluster data type [Liskov and Zilles 1974].
About that time, a paper by Gannon and Horning [1975] presented language
design issues to improve the reliability of programs. One concept that had an
impact on the design of languages was the idea of an explicit interface, and
providing rights to the creator of objects and the users of objects. The encapsulation mechanisms of Simula 67 were refined in the 1970s by the developers
of CLU [Liskov and Zilles 1975; Liskov et al. 1977] and Alphard [Wulf et al.
1976; Shaw 1981]. CLU and Alphard both provided a data abstraction construct
that enforced protection of the data entities, allowing access only to the operations defined for them. The design of CLU [Liskov et al. 1977] was very much
driven by the desire to support software engineering methodology developed
by means of program decomposition, similar to step-wise and structured programming [Wirth 1971a; Dijkstra 1969]. A goal for Alphard was to reduce the
cost and increase the quality of software by developing a program methodology
based on abstraction and verification [Shaw 1981].
Besides CLU and Alphard, Euclid [Popek et al. 1977] also introduced concepts of information hiding. In both CLU and Euclid, the declaration and definitions of a data abstraction always appear together with the header that states
which of the module’s names are to be exported. In CLU, a module (called a cluster) implements a single abstract type [Liskov et al. 1977]. It has an interface
specification, which is the code to create instances and definitions of operators.
Alphard also has the concept of operations to be performed on objects of the
cluster type. Assignment and equality are default operations on “forms.” The
ACM Transactions on Software Engineering and Methodology, Vol. 14, No. 4, October 2005.
442
•
B. G. Ryder et al.
language has explicit rules about accessing a variable of a cluster in the immediately enclosing procedure. The environment, or outer scope, was visible only
by a direct request.
A set of visibility rules for data abstractions was also an important component of research in the early 1980s. C++, developed by Bjarne Stroustrup, had
as one of its primary goals the support of data abstraction and object-oriented
programming [Stroustrup 1987]. Not only did it provide the encapsulation but
also limited the use of data entities. It used the model of private/public to limit
the access of entities in classes. The access right protected was introduced for
inheritance in object-oriented languages.
Cardelli and Wegner defined object-oriented languages by three necessary
characteristics: (i) they contain objects that are data abstractions with a defined
interface and hidden state, (ii) objects have types, and (iii) attributes can be
inherited from super-types [Cardelli and Wegner 1985]. This definition clearly
shows the influence of data abstraction and modularity (i.e., defined interface)
on this programming language paradigm. They cite Smalltalk as an example
of object-orientation with inheritance, and described the standard Smalltalk
hierarchy as an example of reuse that imposes a coherent structure on the
types in the system. C++ and Java added visibility control to the notions of
inheritance and attributes (i.e., fields) already included in Smalltalk.
The abstract data type research results entered mainstream programming
languages in combination with research results on inheritance in objectoriented software design and implementation. The goal of classes and inheritance is to enable reuse as well as code and data sharing. Inheritance allows
new abstractions to be defined as refinements or extensions to existing ones.
Dynamic binding allows a new version of an abstraction to display dynamically
defined behavior.
Data abstraction plus inheritance and dynamic binding define important
characteristics of classes and object-oriented design. All three fundamental
concepts of object-oriented programming—encapsulation, inheritance and dynamic binding—have their roots in Simula 67.
The Simula 67 designers observed from their simulation applications that
processes often share a number of properties, including both data and actions
[Nygaard and Dahl 1978]. These processes were structurally different in some
respects and therefore needed their own declarations—parameterization could
not provide the flexibility needed. They then came up with the idea of subclassing, another name for inheritance. The term inheritance was defined later.3 In
the Simula 67 language, subclassing was done by prefixing. The conceptual
view of prefixing is concatenation of the parent’s class declarations with the
child’s. Thus, if class A is a prefix of class B, B’s objects would include A’s formal
parameters, specification of the formal parameters, class body declarations, and
the class body as well as its own declarations. Thus, not only were the data and
3 Collins
and Quillian defined is-a relationships, introducing them in semantic hierarchies in
1969 [Collins and Quillian 1969]. In Smalltalk-76 [Ingalls 1978] subclasses are described as a
useful mechanism to accomplish code inheritance and allow code reuse and specialization through
overriding.
ACM Transactions on Software Engineering and Methodology, Vol. 14, No. 4, October 2005.
The Impact of Software Engineering Research
•
443
functions of the class inherited but so was the body of the class, which contained
statements that were executed when the class was created.
Simula 67 also had dynamic binding through its virtual concept. Thus, the
method actually used depended on the object’s subclass. Smalltalk also incorporated the notion of object orientation with binding [Ghezzi and Jazayeri 1998;
Goldberg and Robinson 1983] at run time. In the Smalltalk message-based
programming model, each object carries a type at run time.
With the introduction of inheritance, object-oriented languages needed to
supplement the scope rules of objects. Ada, C++, and Java all have rules for
visibility of inherited attributes. Visibility issues included the visibility of private and public members to derived classes.
The issue of multiple or single inheritance has been addressed in both programming language design and software engineering. Subclassing in Simula 67
was designed to be single inheritance; that is, an object of a class can only have
one base class. C++ initially had single inheritance because this was sufficient
in a large majority of cases [Stroustrup 1987]; however, Stroustrup indicated
that there were important concepts for which multiple inheritance is required.
These concepts required a directed acyclic graph to represent their relationships rather than a tree, the single inheritance structure [Stroustrup 1987].
Thus, C++ introduced multiple inheritance, in which a class can inherit from
a number of base classes. However the controversy of single versus multiple
inheritance did not end. Cargill [1993] argued against multiple inheritance by
indicating that is it complicated to learn, write and read. He demonstrated,
using examples of programs with multiple inheritance in the literature, that
multiple inheritance is either improperly used or not used at all. Waldo [1991],
in the same journal, makes a case for multiple inheritance by describing different forms of multiple inheritance and presenting examples where it is useful.
When Java was developed, it used single inheritance with the extra facility of
interfaces, which can be viewed as a form of multiple inheritance. This type of
inheritance is called mix-in inheritance [Scott 2000].
A time line graph of the interactions among abstractions and programming
languages is given in Figure 1. The time line indicates when a particular abstraction concept first appeared in the literature or in a programming language,
subsequent interactions with other software engineering concepts, and its final
incorporation into object-oriented programming languages.
3.2 Types, Polymorphism, and Generics
Strong typing is currently accepted as a fundamental feature of modern programming languages, regardless of whether validated by compile-time checking, type inference or run-time checking. According to Cardelli and Wegner
[1985], in a strongly typed programming language “all expressions are guaranteed to be type consistent although the type itself may be statically unknown.”
In other words, a program in a strongly typed programming language is guaranteed, through a combination of compile-time and/or run-time type checks, to
be type safe; this means that the program is free from type errors during execution. Strong typing ensures the reliability of code and provides an additional
ACM Transactions on Software Engineering and Methodology, Vol. 14, No. 4, October 2005.
444
•
B. G. Ryder et al.
Fig. 1. Time line for data abstraction.
layer of semantic checking of a program. Development of strong typing in
programming languages happened cotemporally with software engineering research on reliability and later, software reuse. It seems clear that the concepts
of strong typing and software reliability reinforced each other, especially since
the early pioneers in imperative language design were also active in software
engineering research. Further, as type systems for programming languages developed notions of genericity and polymorphism, these were directly related to
issues of software reuse.
The main imperative languages designed in the 1960s and 1970s—Algol 60,
Pascal, and PL/I—were designed at a time when the software engineering community was worried about the reliability of code. In the mid-1970s, Barry Boehm
defined software engineering to be “the practical application of scientific knowledge in the design and construction of computer programs and the associated
documentation required to develop, operate and maintain them” [Boehm 1976].
Peter Wegner [1984] talked of the 1950s as a time of stand-alone programs
and the 1960s as a time of development of operating systems and databases.
He stated that the 1970s saw the birth of software engineering, referring to
similarities in the construction of large software systems and large physical
structures such as bridges. The 1980s, in Wegner’s view, saw the development
of interface technologies and the personal computer revolution. The 1990s was
a time of knowledge engineering, the use of intelligent components to build systems (e.g., adaptation). In this temporal framework, the 1970s—the era of Algol
60 and Pascal—was a key time for software engineering, so that the design of
strongly typed languages, which were type safe, coincided with the beginning
of the discipline of engineering software.
C.A.R. Hoare, a member of the IFIP Working Group in Algol (WG 2.1) active
in the original design of Algol 68 [Bergin and Gibson 1996], was the keynote
ACM Transactions on Software Engineering and Methodology, Vol. 14, No. 4, October 2005.
The Impact of Software Engineering Research
•
445
speaker at the first Principles of Programming Languages (POPL) conference
in Boston in 1973. In that talk he spoke of types as “eliminating low-level programming errors when checked by compiler” [Hoare 1974a; van Wijngaarden
et al. 1968]. Furthermore he claimed that types are essential to program design
and documentation. He stated that denoting a declared name and structure or
range of values for every variable is the “most important aspect of clear programming” [Hoare 1974a].
In 1977, John Gannon performed an interesting experiment showing that
declared types and type checking could increase the fraction of programming
errors caught before production of the final program [Gannon 1977]. In addition,
the programmers he studied who were the least experienced, benefited the most
from compile-time typing. In an earlier paper, Gannon and Horning [1975] had
explored issues of language design for reliability through experiments with
students. They stated that declared types provided useful “redundancy” that
caused errors to transform valid programs into invalid programs; they also
noted that type checking caught logical errors, not syntactic errors.
The first widely used programming language to feature explicitly typed variables was Algol 60. In designing Pascal, which was based on Algol 60, N. Wirth
intended the programming language “to make available a language suitable
to teach programming as a systematic discipline” and “to develop implementations of the language that were both reliable and efficient on presently available computers” [Wirth 1971b]. It was the first language to introduce userdefined types, including records and subranges. However, Pascal’s subrange
types caused some problems in its type system, since operations on subranges
could not be checked fully at compile time. In addition, Pascal extended the
data structure constructs in Algol 60 (e.g., arrays) by introducing record structures with heterogeneously typed fields. Pascal allowed variants of records in
which the value of a tag field determined the current type of the variant; however, most Pascal compilers offered no run-time type check of these tags, so the
use of variant records was type unsafe. Pascal also introduced the use of heap
storage with pointer-valued variables that had heap addresses as their values.
Habermann [1973] criticized the subrange construct because there can be
expressions whose operands are subrange type values, but whose result has no
type! Habermann also argued that structures are not types, primarily because
operations on structures are actually operations on their constituent elements,
not on the structure itself; therefore, a characteristic property of a type, that is,
being a value as well as operations on that value, is not fulfilled [Habermann
1973]. These critiques of types in Pascal can been seen as addressing issues
of program understandability and readability as well as good programming
language design.
The unsatisfying lack of orthogonality in design was clearly addressed by
Algol 68 [Tanenbaum 1976; van Wijngaarden et al. 1968], which offered a rich
system of user-defined types. The fact that all types could be used in all contexts rendered Algol 68 easier to learn, although some argued that Algol 68
programs were difficult to understand. The designers of Algol 68 achieved their
goal of being able to validate type safety of programs fully at compile-time, even
while allowing constrained type unions, which safely offered the functionality
ACM Transactions on Software Engineering and Methodology, Vol. 14, No. 4, October 2005.
446
•
B. G. Ryder et al.
of the variant records in Pascal. Unfortunately, Algol 68, although novel, never
attained popularity or general usage outside of the research world.
Cardelli and Wegner [1985] stressed that a type “protects an underlying
untyped representation from arbitrary or unintended use.” They differentiated
the goal of static typing (i.e., complete type checking at compile-time) used by the
early programming languages from the goal of strong typing combining compiletime and run-time type checking to achieve type safety. They characterized
these early programming languages with declared types in terms of their ability
to achieve the goal of strong typing. Some of the problems with array types and
variant records in Pascal have been mentioned previously; in addition, Pascal
failed to require the complete type of procedures passed as parameters to be
specified.
During the late 1960s and 1970s, the emphasis on data abstraction in languages such as Simula 67 and Modula-2, enabled richer notions of types including inheritance (in Simula 67, already discussed in Section 3.1.3), modules with
opaque types at the interfaces to facilitate information hiding (in Modula-2),
and parametric polymorphism (in ML) [Cardelli and Wegner 1985]. During this
same period, the influential International Conference on Reliable Software was
held in 19754 and discussions on types were prevalent.
In 1980, there was a workshop on Data Abstraction, Databases, and Conceptual Modeling attended by researchers from software engineering, databases,
and artificial intelligence [Rowe et al. 1980]. The transcript of a panel considering the topic What is a type? from the viewpoint of each of these research communities, features wide-ranging discussions of this question. A central theme
was the value and practical viability of abstract data types, as a construct with
separate specification and implementation, and with encapsulation of values.
Panelist Mary Shaw’s remarks emphasized the needs for types to convey information about constraints on values and how they can be used. Ira Goldstein,
another panelist, explained the concept of a class with methods from Smalltalk,
(in which he was programming at the time), a world of hierarchical types. Ted
Codd, a panelist, associated a notion of type with ideas in relational databases.
All of these researchers agreed that a notion of type adds structure and definition to the use of values in their respective subfields of computer science.
The emphasis on building software from components in the software engineering community during the 1970s, was reflected in programming language research in data abstraction, object-oriented programming and modularity [Wegner 1984].
At this same time, the designers of Smalltalk were providing a practical
demonstration of how abstract data types with encapsulation might be integrated into a programming language. Smalltalk uses run-time type checking
(type by use). Some research projects defined compile-time checkable types for
Smalltalk [Graver and Johnson 1990]. This goal could be accomplished only
by separating subclassing from subtyping rather than considering them as
equivalent and thereby restricting inheritance. These research results were
4 The
conference was subsequently held annually from 1976–1979, demonstrating the emphasis on
reliability in the research community at that time.
ACM Transactions on Software Engineering and Methodology, Vol. 14, No. 4, October 2005.
The Impact of Software Engineering Research
•
447
not incorporated in the definition of Smalltalk, but may have affected the definition of inheritance in C++ and Java, and the addition of strong typing to
these programming languages.
Ada used strong typing to check consistency of definition and usage of parameters in packages. However, Ada components (or packages) had some weaknesses as well. Wegner [1984] describes how Ada components can communicate
not only through interfaces, but also through global variables and pointers into
the heap. In addition, packages and processes in Ada did not integrate well; for
example, Ada packages were not protected against concurrent access by tasks.
These aspects of Ada hinder it as a basis for software component technology,
according to Wegner. He discussed software reuse in terms of how it relates
to software productivity; most significant are reuse of software components in
different applications and reuse of components in different versions of a given
program [Wegner 1984].
Both Ada and CLU offered generic templates for data abstractions, parameterized by the type of the data. These embodied the notion of generating specific software components of the sort needed for the application, while only
maintaining one copy of the code. These languages offered parametric polymorphism in that an explicit type parameter was used to instantiate the function
argument; this kind of polymorphism was described by Cardelli and Wegner
[1985] as “macro-expansion driven by the type of the arguments.” Wegner remarked that the emphasis on reuse embodied in Ada packages, also implied
an emphasis on portability (i.e., reuse of software across machines), modularity (i.e., reuse of software across programs), and maintainability (i.e., reuse of
unchanged portions of code after other portions are changed) [Wegner 1984].
Frankel [1993] discussed how Ada generics “encourage and assist the implementation of reusable software.” He cited Ada’s strong typing and separation
of package specification from implementation as language features supporting
abstraction, and necessary for reuse to be accomplished in an efficient manner.
Frankel emphasized that building a generic version of code isolates the reusable
portion from the part that is unique to each user. Both of the kinds of reusability
he discussed—as-is and with-modification—can be realized with generics.
Research in the programming language design community at this time examined the relation between subtyping and subclassing, and their influence
on possible choices for object-oriented programming language design [Madsen
et al. 1990]. Madsen et al. contrasted the two uses of subclassing, for establishing a type system through specialization and for code sharing. They discussed
a type system as a “means for detecting certain program errors, type errors”
and considered combinations of compile-time and run-time type checking to
achieve type safety, also including the checking needs of parameterized types.
They expected a type system to allow desirable “early error reporting” when
compile-time checking is possible. This paper is an example of many research
papers in the programming language design community of the time, concerned
with building type systems that would enhance program reliability in the new
language paradigm.
The emergence of object-oriented programming languages in the 1980s and
1990s was cotemporal with increasing concern in the software engineering
ACM Transactions on Software Engineering and Methodology, Vol. 14, No. 4, October 2005.
448
•
B. G. Ryder et al.
community about how to design and build large, modular systems from pieces
with clearly defined interfaces using teams of programmers. The ability to ensure software reliability was questioned and more emphasis was placed on
reuse of tested or provably correct software.
Designed in the mid-1980s, C++ was the first widely used object-oriented
language for commercial software. C++ offered the creator of a new type (or
class) the ability to define implicit type conversions between that type and another; these are used by the compiler for resolving types in uses where coercion
is necessary. Murray [1988] discussed problems with this language feature that
can occur when too many conversions are defined, leading to ambiguities that
require casting to fix. In addition, this feature may make it possible for new
declarations to break existing code. This discussion was in the context of C++
libraries, whose usage was growing at the time. Translating these concerns to
software engineering terms, as a programming language expert Murray was
worrying about effective software reuse, support for program understanding,
and code extensibility.
Wegner [1984] viewed inheritance in classes as structuring components so
that they are easily reused. He compared libraries in Ada, which are flat in
structure, with libraries in Smalltalk, which have a tree structure. He suggested the idea that object-oriented language mechanisms can embody semantic knowledge that can aid in software reuse.
Reuse research in the late 1980s focused on libraries, reusable components,
and reusable support environments [Prieto-Diaz 1993]. There are many different types of reuse considered—ideas, artifacts, processes—but the connection
with programming language design is best viewed from the perspective of ad
hoc and compositional reuse. Ad hoc reuse involves reuse of libraries with userfriendly retrieval mechanisms; compositional reuse refers to composing existing
components to furnish parts of new systems. Both of these involve reuse of code,
with (black box), or without (white box), modification [Prieto-Diaz 1993].
The standardized interfaces of the C++ STL and the Java JDK can be seen as
providing tools for these sorts of reuse. Stroustrup stated that C++ templates
were intended to be added to the language when their design and implementation issues were fully explored. The need for standardized libraries in C++
was clear in 1988 [Stroustrup 1993] when he first presented templates at the
USENIX C++ conference. He chose to use generics because they provided static
type checking and cited the provision of good libraries as desirable, and almost
necessary, for acceptance of an object-oriented programming language. Looking
at Dr. Dobb’s Journal and the C/C++ Users Journal from the 1990s, we find
several articles about programming with the standard template library (STL),
evidence of language design responding to reuse issues [Plauger 1995; Keffer
1995]. The addition of generics to Java 1.5 and the strong interest expressed
in the generics offered by C++ are further evidence that a concern with reuse
issues affected programming language design.
Strong typing was added to programming languages to enhance software reliability, at a time when this was a focus of the software engineering research
community. The development of user-defined packages and generics were direct responses to concerns about software reuse. The time line graph showing
ACM Transactions on Software Engineering and Methodology, Vol. 14, No. 4, October 2005.
The Impact of Software Engineering Research
•
449
Fig. 2. Time line for Types and Exceptions. The arrows in the diagram on the right show relations
between programming language and software engineering concepts, and the times of their first
appearance. The programming languages listed to the left of the time line are shown at their
inception year. Some of the concepts on the right appear in some of the programming languages on
the left.
the interactions between types in programming languages and the software
engineering research related to types is given in Figure 2.
3.3 Exceptions
Exceptions are features that were added to programming languages to provide
the programmer the capability to specify what should happen when unusual
execution conditions occur, albeit infrequently. Originally in programming languages, such atypical conditions resulted in control being relinquished to the
operating system that then aborted the execution of the program in a forced
termination. But when such conditions, however infrequent, can be anticipated,
the programmer can write code to react to them and to gracefully handle them.
Exceptions and exception handler codes are the mechanism provided by modern
programming languages to address this problem.
The historic introduction and development of exception mechanisms in programming languages is intertwined with considerations of software reliability
and fault-finding in software engineering. The first precursor of an exceptionlike construct is found in Lisp 1.5, a language designed by John McCarthy in
the mid-1950s [Gabriel personal communication; McCarthy et al. 1965]. This
language featured a function named errset that allowed the Lisp interpreter
and compiler to gracefully exit from an error when one occurred. This function used a mechanism for counting the number of cons operations performed
within a loop in order to stop an unbounded computation. The errset construct
ACM Transactions on Software Engineering and Methodology, Vol. 14, No. 4, October 2005.
450
•
B. G. Ryder et al.
allowed suppression of error statements and a program restart under certain
conditions after an error occurred [McCarthy et al. 1965].
PL/I, a programming language developed by IBM and representatives of its
user community (i.e., SHARE [Radin 1981]) concurrently with System 360 in
the mid-1960s [Radin 1981], included some facilities for dealing with control
flow that were atypical for a high-level language. Previous languages had had
few facilities for dealing with exceptional conditions during execution, such
as end of file, overflow, bad data, and so forth. The PL/I language designers
wanted to give programmers the ability to write reliable and safe programs
totally in their language [Radin 1981]. The ON condition feature was introduced
into PL/I to allow specification of the actions to be taken when one of a set
of 23 unusual, but anticipatable situations occurred during execution. Userdefined ON conditions were also allowed. There were several problems with this
mechanism: (i) an ON unit was dynamically associated with its invocation by
an exceptional condition occurrence, rather than being associated lexically with
the excepting statement or operation, and (ii) global variables were often used
to communicate data to the ON unit code [Library 1970; MacLaren 1977; Liskov
and Snyder 1979].5 The construct proved difficult to use, in part because the fixup actions were to take place in the state that pertained when the ON statement
was executed. Nevertheless, the philosophy of programming language design
for reliability demanded that this facility (or something like it) be included in
the programming language definition.
By the mid-1970s, software reliability was a strong concern in both the software engineering and programming languages communities. In March 1977,
SIGPLAN, SIGOPS and SIGSOFT cosponsored the Conference on Language
Design for Reliable Software in Raleigh, NC. The Communications of the ACM
featured a special issue on language design for reliable software in August 1977.
The exception mechanisms in today’s languages were influenced by research
in software engineering. In the Communications of the ACM in December 1975,
John B. Goodenough discussed issues in exception handling, classifying the
types of exception usages as (i) dealing with domain or range failure of an operation (ii) indicating the significance of a result, or (iii) permitting monitoring
of an operation. When range failure is indicated, the operation may need to
be aborted, retried, or terminated, yielding partial results. A domain failure
requires modification of the input or an abort of the operation. Exception type
(ii) is not a range failure, but requires that additional information be passed
back to the user about the operation. Exception type (iii) is usually resumed
after the user examines the information about the operation passed back by the
exception. Not all of these are error conditions; Goodenough [1975a] described
them “as a means of conveniently interleaving actions belonging to different levels of abstraction.” After reviewing some existing exception mechanisms of the
time, Goodenough discussed requirements for good exception handling, which
should “help prevent and detect programmer errors” according to Gannon and
5 Note:
no parameters were allowed in ON conditions; standard condition built-in functions were
provided to query information such as the name of the procedure in which the condition was experienced [Library 1970]. See also http://www.kednos.com/pli/docs/USERS GUIDE/6292pro 023.html.
ACM Transactions on Software Engineering and Methodology, Vol. 14, No. 4, October 2005.
The Impact of Software Engineering Research
•
451
Horning [1975]. He argued the effectiveness of lexical (or static) association
of handlers with operations that may throw exceptions. These included both
language-defined and user-defined (subroutines) operations, with explicit declaration of those exceptions that may be thrown as the result of a call. He
advocated compile-time checking of the completeness of exception handling.
His model of exception handling included the possibility of resuming execution
as well as termination, and allowed the use of default exception handlers.
Goodenough’s [1975a] paper codified the ideas presented in his earlier paper [Goodenough 1975b] at the second Symposium on Principles of Programming Languages (POPL) (January 1975), the major programming languages research conference at that time. This is an example of how software engineering
researchers, concerned about issues of software reliability, directly contributed
to programming language design.
In addition to Goodenough’s contributions to exception handing, during this
same year Brian Randell described his own construct for error detection and
recovery [Randell 1975] in a paper delivered at the International Conference on
Reliable Software. He defined a structured mechanism called recovery blocks
which were to be used when an unanticipated fault occurred. Horning described
exception handlers as “useful” and “intended to cope with particular anticipated, but unusual, situations” [Horning 1979]. Horning suggested that recovery blocks and exceptions could coexist in the same code as what he termed “an
attractive compromise.”
During the period of these software engineering discussions on how programming languages should be designed to facilitate the handling of faults, a new
programming language, CLU [Liskov and Zilles 1975; Liskov et al. 1977; Liskov
1993] was designed based on the ideas of abstraction and specification. CLU
was designed to enable good program construction of moderate-sized (by modern standards) codes, emphasizing the use of software engineering techniques
such as data abstraction and program verification, as well as programming
language theory in terms of formal (algebraic) specifications. In the chapter
on exceptions, Liskov and Guttag [1986] described the need to “program defensively,” that is to write each procedure “to defend itself against errors.” A “robust
program” is “one that continues to behave reasonably even in the presence of
errors” [Liskov and Guttag 1986]. This is a strong emphasis on this aspect of
programming language design being motivated by software engineering considerations; this fits well with Goodenough’s [1975a] emphases.
Liskov and Snyder [1979] discussed the design of the exception handling
mechanism in CLU and gave credit to Goodenough specifically for influencing them through his paper [Goodenough 1975a]. They discussed their design
with regard to other previous approaches, as well. For example, the CLU model
expects that exceptions not handled locally where they are raised, will be handled by the immediate caller of a procedure. (Of course, the handler code can
rethrow an exception to pass it upwards through the call chain, one link at a
time.) Liskov and Snyder pointed out that this is consistent with Goodenough’s
model, but not with the definition of exception handling in PL/I or Mesa. Their
discussion of the resumption versus termination model of exception handling,
explicitly referenced Goodenough’s model in his 1975 paper [Liskov and Snyder
ACM Transactions on Software Engineering and Methodology, Vol. 14, No. 4, October 2005.
452
•
B. G. Ryder et al.
1979]. Thus, it is clear that for CLU, programming language design was directly influenced by software engineering research, although the researcher
(Goodenough) presented his ideas to both communities [Goodenough 1975a,
1975b].
The Ada programming language was defined in the late 1970s according to
specifications set by the US Department of Defense, as a modern programming
language that was to be the universal software lingua franca for their projects.
The Rationale for the Design of the Ada Programming Language [Ichbiah et al.
1979] described the evolution of the Green candidate language written as
part of the process of defining what was to become standardized as Ada. The
Rationale was written to record design decisions and influences on the Ada language. The chapter on exception handling in the Rationale references the earlier Goodenough article [Goodenough 1975a] in two ways. It uses Goodenough’s
classification of exceptions as either allowing program execution termination
or resumption after handling, but rejects the resumption model of handling in
favor of always terminating execution.
The Rationale also references a technical memo by Bron et al. [1975] that
discussed desirable properties of an error-handling mechanism to provide for
program termination under exceptional conditions. These desirable properties
were formulated so that operational semantics could be defined for those programs requiring this construct. The suggested programmer-controlled termination mechanism was associated with a block of operations; it allowed programs
to be written with the usual input assertions, with the handling of bad input not
affecting program structure, and resulting in a cost only to those blocks where
it might be used. These ideas influenced the design of Ada exception handling.
The Rationale also refers to the Bliss language [Wulf et al. 1971] developed
at DEC in the mid-1970s as influential in the definition of Ada exceptions. The
Rationale emphasizes that the designers wanted to being able to prove the
correctness of programs [Luckham and Polak 1980] and to optimize programs
with exceptions. These properties led to the rejection of the resumption model,
which renders both of these difficult.
Perry in his ICSE’89 award-winning paper entitled The Inscape Environment
discussed the specification and design of exception handling as an integral part
of system development when large systems are built by many developers. His
model for specifying exceptions is based on an extension of Hoare’s input/output
predicates [Hoare 1969; Perry 1989]. Perry examined the Larch specification
language [Guttag et al. 1985], but preferred a nonalgebraic approach. It is clear
from his paper that Perry was influenced by programming language technology in his choice of how to specify exceptions and their handling in Inscape,
whose goal was to provide an integrated software development environment
for large groups of developers building large software systems. He described
a design in which module interface specifications include descriptions of both
exceptions to be handled and handling strategies. His program construction
tool checked that exceptions are handled as specified in the constructed code.
Changes in exception handling are considered by the change evolution manager component of his system. The Inscape environment shows that the treatment of exceptions in programming languages in the late 1980s influenced
ACM Transactions on Software Engineering and Methodology, Vol. 14, No. 4, October 2005.
The Impact of Software Engineering Research
•
453
software engineering research on the design of programming development
environments.
The subject of exception handling and how it should be added to C++ was
a major topic of debate at the 1990 USENIX C++ Conference. Koenig and
Stroustrup [1993] argued for their model of exceptions as objects (which was
eventually incorporated in C++) in their 1990 USENIX C++ Conference paper. They also referred to the termination model of PL/I, CLU and Modula-3
[Harbison 1992] as preferable to any resumption model. Essentially, C++ exception handling seems an outgrowth of the techniques defined in CLU and
Modula-3. Statements are executed within a try block, which has associated
catch blocks (typed exception handlers) that are handlers for some of the exceptions that can be thrown from within the try block. This design was influenced
by the work on fault-tolerant systems by B. Randall [Ellis and Stroustrup 1990].
Again we see programming language design being influenced by software engineering research. Exceptions are handled locally or by walking up the call
chain to find the first appropriately typed handler. The set of exceptions possibly thrown by a function (directly or indirectly) can be listed as part of the
function declaration. Violations of this exception specification are dealt with
at run-time, not compile time as in Java. This decision to avoid compile-time
checking was in part due to the ability to link to C, functions that have no
explicit exception constructs. When a function with an exception-specification
throws an exception not on its list, then the function void unexpected() is
called and execution is usually halted.
More recently, aspect-oriented programming describes how crosscutting concerns in an object-oriented program can be addressed by new compositional
mechanisms in addition to inheritance. At ICSE 2000, this new paradigm was
used by having aspects [Kiczales et al. 1997] express the detection and handling of exceptions [Lippert and Lopes 2000]. The main idea was to reduce the
amount of redundant handling code in a program. The specific language used,
AspectJ, allowed abstract crosscuts (i.e., templates) that can be instantiated
in many different locations where exception handling required the same actions. In their case study using a large Java application containing 750 classes
(including 150 test classes), the authors reduced the size of the exception handling code from 10.9% of the total lines of code to 2.9% lines of code on average.
This represented a significant reduction in catch statements over the original
program. This research paper is indicative of the strong interaction between
software engineering and programming language research and researchers. In
this case, a paper describing how to code exceptions (a programming language
mechanism) to ensure program reliability (a software engineering desiderata)
through the use of aspects (a programming language mechanism) was presented at the premier annual software engineering conference.
As another example of the close tie between the disciplines, Robillard and
Murphy [2000] discussed in their paper why the design of exception handling
in an application is so difficult. The focus is software design, namely how to
regularize the exceptions that are passed between components of a software
system, but intertwined in the discussion is the essential character of exceptions
and their handling in Java. The technique applied is software compartmenting,
ACM Transactions on Software Engineering and Methodology, Vol. 14, No. 4, October 2005.
454
•
B. G. Ryder et al.
first described by Litke [1990] at the TRI-Ada 1990 Conference. This technique
divides software into compartments, defines precise and complete exception
interfaces for each compartment, and automatically verifies the conformance
of the actual program to compartment specification [Robillard and Murphy
2000]. The paper described a case study of software compartmenting using the
authors’ own Java tool as data. The authors also developed guidelines for Java
exception usage. In their discussion, they referred to exception handling both
in CLU and C++. This is another software engineering research project that
builds on programming language design and research.
Figure 2 provides a time line for concepts related to types and exceptions.
3.4 Concurrency
The theoretical foundation of the concurrency that is expressed in programming languages today was laid in the 1960s and early 1970s. Initially, the need
for concurrency in programming languages was driven by applications, such
as simulation in Simula 67 [Dahl and Nygaard 1967]. The initial concurrent
construct that appeared in Simula 67 was a coroutine, which allowed a quasiparallel execution of the program. In 1965, Dijkstra published an important
paper in which he described how to use concurrency to express the solution
to the problem of sharing data among concurrent processes. In 1968, Dijkstra
[1968a] showed how to use semaphores to solve a variety of synchronization
problems and introduced the famous dining philosophers problem.
At the same time, Algol 68 [van Wijngaarden et al. 1968] was the first programming language to allow expression of true concurrency by the programmer
through the parbegin-end construct. Later, [Courtois et al. 1971] introduced the
readers/writers problem and formulated solutions to it using semaphores.
During the 1970s, most concurrency was expressed at the operating system level, through time-sharing operating systems with multiprogramming.
In his HOPL-II article on Concurrent Pascal, Brinch Hansen relates how “the
idea of monitors evolved through discussions and communications among E. J.
Dijkstra, C.A.R. Hoare, and me (Brinch Hansen) during the summer and fall of
1971” [Hansen 1996]. Influenced by the work of Dahl in Simula 67, the concurrency model of Concurrent Pascal, developed in the mid-1970s, refined the definition of monitors into a key language construct [Hansen 1972, 1975]. Brinch
Hansen describes a monitor as “a set of shared procedures which can delay and
activate individual processes and perform operations on shared data” [Hansen
1996]. Conceptually, monitors can be viewed as an extension of the idea of an
abstract data type to a concurrency setting.
C.A.R. Hoare later described his implementation of monitors [Hoare 1974b]
built with semaphores, for shared memory concurrency models in operating
systems. According to Brinch Hansen, Hoare’s ideas were available in public
presentations in 1972 and 1973. Thus, these two researchers codeveloped the
monitor concept. Later, in his seminal paper in 1978, Hoare described notational
tools for programming languages to express concurrency, that is, communicating sequential processes (CSP) for message-passing concurrency models [Hoare
1978]. Clearly, there was close interaction between programming language
ACM Transactions on Software Engineering and Methodology, Vol. 14, No. 4, October 2005.
The Impact of Software Engineering Research
•
455
Fig. 3. Time line for Concurrency. The arrows in the diagram on the right show relations between
constructs related to concurrency, with the times of their first appearance. The programming languages listed to the left of the time line are shown at their inception year. Not all the programming
languages shown contain concurrency constructs.
designers and software engineering researchers in these early days when the
two disciplines were beginning to distinguish themselves from one another.
Ada [DOD 1980], also designed in the mid-1970s, was the first widely used
programming language designed with language constructs for concurrency,
based on Hoare’s message-passing CSP. Java [Gosling et al. 1996], introduced
in the mid-1990s, advanced the monitor concept by encapsulating access to
shared data by synchronized methods and code blocks.
As is evidenced by this historical narrative, the early unified software engineering and programming language community heavily influenced the concepts and the notation used to express concurrency in programming languages.
There is also evidence that the more recent software engineering research has
focused on building tools and techniques for managing and analyzing concurrent programs. This includes work in program analysis, testing, anomaly detection, replay and debugging of concurrent programs. Surprisingly, except for the
early research in the 1960–1970s, there has been little influence as evidenced
through published works of software engineering research on the design of concurrent constructs in programming languages, although language constructs
for concurrency continue to be developed [IEEESW 1989].
The time line for concurrent constructs is given in Figure 3.
ACM Transactions on Software Engineering and Methodology, Vol. 14, No. 4, October 2005.
456
•
B. G. Ryder et al.
4. VISUAL PROGRAMMING: FROM RESEARCH TO PRACTICAL USE
This report thus far has focused on the impact of software engineering research
on programming languages that have textual syntax, but visual syntaxes for
programming have also become important in recent years, as the popularity
of Visual Basic helps to demonstrate. Although software engineering research
generally aims to improve the quality of software and the processes, languages,
and tools used to create this software, most of this work focuses only indirectly
on the human programmers who create the software. In contrast to this majority, research on visual programming aims directly at the human aspects of
programming. Therefore, in this section, we focus on the evolution of visual
programming properties that are becoming mainstream, as they relate to the
cognitive problem-solving needs of human programmers.
Visual programming refers to any system that allows a program to be specified using two- (or more) dimensional expressions, such as diagrams, icons,
color coding, multi-dimensional annotations, and/or even graphical actions
themselves [Burnett and McIntyre 1995]. When multi-dimensional expressions, called visual expressions, are the syntax of a new programming language,
the system is called a visual programming language. For example, Prograph
[Cox et al. 1989] was a research (and later, commercial) object-flow visual programming language in which components of the classes were specified by placing icons, and whose method syntax consisted of dataflow diagrams. Another
example is Peridot [Myers 1990], a research visual programming language for
programming user interfaces, part of whose syntax was the demonstration of
actions on data objects. When the visual expressions are used to provide a
supporting environment for a preexisting textual programming language, the
system is a visual programming environment. For example, Pecan [Reiss 1984]
was a research visual programming environment for Pascal. Snapshots of visual programming approaches of the 1980s, when many of these approaches
emerged, are shown in Figure 4.
In general, the aim of visual programming is to reduce the cognitive burden on human programmers, through devices that reduce the mental effort
required to access and make sense of the available information. Although visual programming research spans multiple subdisciplines of computer science,
a large portion of it has taken place within the software engineering community.
The impact of visual programming research upon modern programming languages lies in two areas. The first area of impact is the use of visual communication devices to illustrate programs and their behavior in software development environments for professional programmers. Today visual devices
that descended from early visual programming research can be found in many
modern software development environments. The second area of impact is the
design of visual programming languages that are viable for audiences who are
not expert programmers in traditional programming languages. Visual Basic,
which is of great practical importance given its wide usage, demonstrates both
of these impact areas.
In other sections of this article, we have discussed software engineering research culminating in programming language constructs that enable language
ACM Transactions on Software Engineering and Methodology, Vol. 14, No. 4, October 2005.
The Impact of Software Engineering Research
•
457
Fig. 4. Snapshots of 1980s era visual programming systems: Clockwise from left: Prograph programming was done by drawing dataflow diagrams (left; figure re-created from Cox et al. [1989]),
and Prograph objects arriving at the ports on the dataflow diagram could be inspected by doubleclicking to reveal the object structure and values shown (top; figure is from TGS Systems [1990]).
PECAN (right) featured a variety of graphical and textual views of Pascal programs, and visually
highlighted the portion of the code being executed in both of the views shown (figure is from Reiss
[1984]). Peridot allowed programmers to specify user interfaces by directly placing the GUI objects
as desired and demonstrating the objects’ responses to GUI events (bottom; figure is from Myers
[1990]).
processing systems to automatically detect or prevent certain reliability issues
in a program. For example, abstraction constructs allow some inappropriate
data accesses to be prevented by the system, and type checking allows the
system to detect type errors. However, the primary influence of the visual programming work was less on new language constructs per se, and more on language properties that are realizable by visual programming mechanisms. Further, these properties are tied to enabling human programmers, rather than
language processing systems, to detect or avoid certain reliability issues in a
program. We begin by considering four properties that emerged from the visual programming research done in the software engineering community prior
to 1991: concreteness, directness, explicitness, and immediate visual feedback.
We then show examples of how these properties have been instantiated in Visual Basic, which emerged in 1991.
ACM Transactions on Software Engineering and Methodology, Vol. 14, No. 4, October 2005.
458
•
B. G. Ryder et al.
4.1 Emergence of Visual Programming Properties
Although there were a few pioneering works in visual programming in the
1960s and 1970s (e.g., Sutherland [1963, 1966]; Smith [1977]), in the 1980s
visual programming gathered momentum as a research area in the programming language and software engineering communities, initially following two
approaches. One concentrated on mapping each traditional programming construct one-to-one to an icon (e.g., Glinert and Tanimoto [1984]). The other concentrated on new visual approaches to programming that deviated significantly
from the traditional methods, such as programming by wiring together constraints (e.g., Borning [1981]) or by demonstrating desired behaviors on the
screen (e.g., Rubin et al. [1985]). Many of these systems had advantages that
seemed exciting and intuitive when demonstrated with toy programs, but ran
into difficult problems when attempts were made to extend them to more realistically sized programs. These problems led to an early disenchantment with
visual programming, causing some to believe that visual programming was
inherently unsuited to real work.
To address these problems, visual programming research moved in two directions. The first direction involved the incorporation of visual expressions
into integrated programming language environments, for those specific parts
of software development in which visual expressions demonstrated obvious advantages for human programmers. The second direction, involving the development of domain-specific languages, increased not only the kinds of applications
suitable for visual programming from start to finish, but also broadened the set
of people who could program.
4.1.1 Visual Programming via Programming Environments. Starting
in the early 1980s, integrated programming environments such as
Smalltalk [Goldberg 1984], the Cornell Program Synthesizer [Teitelbaum
and Reps 1981], Cedar [Teitelman 1984], Pecan [Reiss 1984], and Gandalf
[Habermann and Notkin 1986] began incorporating visual expressions. (For
a history of the increasing use of visual expressions during the evolution of
language environments, see Ambler and Burnett [1989].) The synergy of visual
language research with language environment research led to the advent of
practical visual programming environments for traditional languages. The visual expressions were used for selected aspects of software development (e.g.,
for GUI programming), for explicitly depicting relationships and flow, and for
visually combining textually-programmed units to build new programs (e.g.,
Hirakawa et al. [1990]). Eventually, this merging combined syntax-directed
editing and grammars for both textual and visual expressions (e.g., Chang et al.
[1989], Crimi et al. [1990], and Helm et al. [1991]), which further increased the
viability of incorporating visual expressions into programming environments.
The successes and failures from these early approaches led to investigation
into more general properties of visual programming, and how these properties
were linked with supporting human programmers’ software development efforts. For example, one critical reason for the success of incorporating visual
expressions into programming environments was that doing so promoted the
property known as directness or closeness of mapping [Green and Petre 1996]:
ACM Transactions on Software Engineering and Methodology, Vol. 14, No. 4, October 2005.
The Impact of Software Engineering Research
•
459
allowing the programmer to express solutions to a subproblem (e.g., GUI layout) using a notation similar to the problem itself (e.g., by drawing the desired
layout). Directness is important because it avoids the cognitive burden and associated error potential of translating from one way of describing ideas to a
different way.
Other properties supporting human problem-solving are explicitness, concreteness, and immediate visual feedback. Explicitness in depicting relationships and dependencies, such as via dataflow diagrams, eliminates the errorprone work of tracking down these relationships manually. The property of
concreteness denotes working with concrete data values to express or explore
program logic. Consider a function or procedure definition, which is abstract
in the sense that it does not include any actual data from a specific instance
of invocation. When writing such a function, programmers have to model (in
their heads or on paper) the actual data that will be present when the function
is invoked. This modeling process is an additional attention cost that concrete
sample values can help to eliminate. A system’s ability to provide immediate
visual feedback about program semantics, such as immediately showing the
calculated result on values, is facilitated by concreteness. This feedback feature has been shown to be heavily used in problem-solving by both novice and
expert programmers [Green and Petre 1996]. As visual programming research
matured, it became evident that the support visual expressions can lend to
properties such as those described above, not the use of visual expressions per
se, is the aspect of visual programming important to human productivity in
problem solving and programming.
4.1.2 Domain-Specific Visual Programming Languages. The other direction followed by visual programming researchers was to increase the kinds
of applications suitable for visual programming from start to finish, through
the development of domain-specific languages. These researchers incorporated
the previously discussed properties. In addition, because many domain-specific
languages are aimed at specific types of audiences as well as specific types of
applications, these researchers began to focus more carefully on the audiences
for whom their languages were intended. Thus, visual programming became
an enabling mechanism for a phenomenon known as end-user programming,
in which people not trained as programmers develop their own applications.
Designing a visual language for use in a specific problem domain by a specific
audience is an example of language research that aims at supporting the directness property. It allows people to program directly in their domain-specific
notations using visual expressions (e.g., icons and diagrams) reflecting the particular abstractions, diagramming traditions, and vocabulary specific to that
domain, instead of requiring people to translate their vocabularies to traditional programming language terminology. This approach produced a number
of successes, first in research and then in the marketplace. For example, today
such audiences include teachers creating educational simulation programs by
demonstration (e.g., Roschelle et al. [1999]) and laboratory scientists, who can
graphically wire measurement data through icons representing summarization and visualization tools using LabView, a commercial visual programming
ACM Transactions on Software Engineering and Methodology, Vol. 14, No. 4, October 2005.
460
•
B. G. Ryder et al.
Fig. 5. Visual Basic. The center window shows Visual Basic’s direct placement of GUI
objects in the desired GUI layout. The StrikeThrough subobject has been selected, causing its type to be displayed along with its “properties” (lower right of the screen shot),
i.e., the object’s data members’ names and values.
language for the domain of laboratory measurement [Baroth and Hartsough
1995].
4.2 Visual Basic’s Instantiations of Visual Programming Properties
The properties described in the previous section can be seen in three of Visual Basic’s features: its support for GUI programming, its use of visual programming in its integrated language environment, and its programming-bydemonstration features (found in the language subset known as Visual Basic
for Applications or VBA).
The precursor to Visual Basic first took shape during 1988–1990 as a visual
programming language for Windows shell programming not associated with
Basic [Arnson et al. 1992; Cooper 1996]. Microsoft purchased the concept, married it to Basic, and Visual Basic made its debut in 1991. In the 1980s and early
1990s, the visual programming properties discussed previously had not yet become widely recognized as such; rather, researchers were still experimenting
with specific features instantiating those properties. Thus, it is not surprising
that Visual Basic’s instantiations of these properties correspond to the specific
features of the pioneering systems such as those in Figure 4.
For example, the directness property figures prominently in one of the best
known features of Visual Basic, namely the ability to specify a GUI layout by
directly manipulating the visual properties of GUI objects (e.g., their placement
and size). The version of this feature in Visual Basic is shown in Figure 5. The
center window shows the support for programmers to be able to directly place
objects in a GUI as desired. This feature was pioneered in the Peridot visual
language [Myers 1990], as can be seen by comparing this window with Peridot’s
version (bottom of Figure 4).
ACM Transactions on Software Engineering and Methodology, Vol. 14, No. 4, October 2005.
The Impact of Software Engineering Research
•
461
An instantiation of the immediate visual feedback property can also be seen
via the GUI objects in Figures 4 and 5. As these figures show, in Visual Basic
(as well as Peridot), moving and resizing the source code (i.e., elements of the
drawing on the screen) is immediately reflected in how the GUI appears, since
the representation of the source drawing and its ultimate result are one and
the same.
The immediate visual feedback property is due in part to the use of concreteness in Visual Basic in the same manner as in Peridot. As Figure 5 shows in its
center window, programming is done via specific instances, not just abstract
variables, in performing manipulations of GUI objects. Also, the StrikeThrough
subobject has been selected, causing its properties to be displayed in the properties pane (lower right of Figure 5), which lists the object’s attributes/data
members in a column on the left along with their values in the right column. The
programmer can access and manipulate these properties, a capability reminiscent of the Values window of Prograph (top of Figure 4). In Prograph, as later in
Visual Basic, any value (object) can be opened via direct manipulation, causing
the object’s type to be shown (highlighted top left of Value window), along with
its attributes’/data members’ names (below the icons) and values (above the
icons).
The VBA subset of Visual Basic is embedded in several Microsoft products,
including Excel, PowerPoint, and Word. VBA has been the language to support
end users in the construction and editing of macros. Although the user can
create these macros by typing in VBA directly, the more usual approach is
to begin by demonstrating the desired logic via example (as in Peridot). For
example, in Excel a user can demonstrate a macro by recording the actions
they perform on Excel objects (cells, formulas, spreadsheets, etc.). VBA’s support
for programming-by-demonstration is another instantiation of the directness
property.
The explicitness property can also be seen in VBA. In VBA, when a user
chooses to step through execution one line at a time, the editor highlights the
lines being executed, a feature found in other modern visual environments as
well. This feature dates back to the Pecan visual programming environment
of 1984-1985 [Reiss 1984], which graphically highlighted the portions of code
being executed, as shown at the right side of Figure 4. This is an instantiation
of the explicitness property, since the system is explicitly depicting control flow
as the system executes.
Visual Basic has, of course, also incorporated numerous language features
that are not related to visual programming. For example by 1992, Visual Basic
included the concept of objects, which eventually led to incorporation of a form
of classes in 1996.
4.3 Software Engineering Trends in Modern Visual Programming Research
Three recent software engineering trends have emerged in visual programming research. First, software engineering research regarding language features such as abstraction, exception handling, and types, discussed in Section 3,
has begun to have significant impacts on visual programming language features
ACM Transactions on Software Engineering and Methodology, Vol. 14, No. 4, October 2005.
462
•
B. G. Ryder et al.
in the last few years. In order for visual programming languages to scale to increasingly large software projects, researchers have worked to devise ways to
incorporate more powerful language features without loss of the properties that
assist human problem solving. Burnett et al. [1995] surveys the beginnings of
visual programming research in these directions.
Second, with the advent of end-user programming, emerging projects have
begun to consider the concept of end-user software engineering [Burnett et al.
2003]. This research draws from results of software engineering research into
how to support phases of the software lifecycle beyond the coding stage. Combining this research with visual expressions, machine learning techniques, and
emerging HCI research, researchers are now developing new software engineering methodologies to help end-user programmers reduce defects by supporting them beyond the coding stage, such as with incremental visual testing
[Rothermel et al. 1998], semi-automatic defect detection [Bottoni et al. 1997;
Miller and Myers 2001; Raz et al. 2002], and tightly integrated assertion mechanisms [Burnett et al. 2003].
Third, as visual programming research has matured, researchers have
learned that visual programming research is not a matter of learning whether
visual expressions are overall superior to text-only notations: every notation
has strengths and weaknesses [Green and Petre 1996]. Rather, the essence of
visual programming research is to learn how to harness visual programming’s
expressive power to support particular properties that assist human cognition,
such as the closeness of mapping, concreteness, explicitness, and immediate
semantic feedback properties discussed above. Progress in this direction has
been made largely through multidisciplinary work that draws not only from
software engineering and language research but also from human-computer
interaction (HCI) research, with a strong emphasis on empirical work. One example of this direction is the work of Pane et al. [2002], who devised a domainspecific programming language only after performing empirical work with the
intended audience, to elicit the principles and constructs that were eventually
used in the design of the language. This increasing emphasis on drawing from
and contributing to empirical foundations is having an important impact on
the measurable effectiveness of visual programming. Further, by demonstrating the impact of empirically-based research involving humans on the genuine
effectiveness of software engineering techniques, an approach long advocated
by several software engineering researchers [Gannon 1977; Basili et al. 1986;
Tichy 1998] but too rarely followed, visual programming research makes a valuable methodological contribution.
The time line graph for visual programming is provided in Figure 6.
5. INTERVIEWS WITH PROGRAMMING LANGUAGES DESIGNERS
To obtain firsthand historical information about the influence of software engineering research on programming language design, a set of language designers were contacted by email or phone and asked about influences on
their work. Designers who responded to us were Professor Boris Magnusson
(Simula 67), Professor Niklaus Wirth (Pascal, Modula), Dr. Jean Ichbiah (Ada),
ACM Transactions on Software Engineering and Methodology, Vol. 14, No. 4, October 2005.
The Impact of Software Engineering Research
•
463
Fig. 6. Time line for visual languages.
Dr. Brian Kernighan (scripting languages), Dr. Bjarne Stroustrup (C++), Dennis Canady (Visual Basic), Tim Lindholm (Java), and Tucker Taft (Ada 95).
Each of the participating designers was sent the list of questions below and
then either answered them by email or phone.
The following questions were asked about the influences on the interviewees’
language designs, where xxx stands for the particular programming language
with which the designer was involved.
(1) What were the problems that you were addressing in your design for PL
xxx?
(2) What programming practices or software engineering research do you think
influenced your language design, positively or negatively?
(3) Can you recollect any of the papers you were reading, the conferences you
were attending and the people you were talking to when you were designing
your language xxx?
(4) Were there specific applications that drove your design?
(5) If you were to design a programming language today, how would it differ
from current programming languages?
Dr. Kernighan, designer of awk, indicated that he thought there was little
influence of software engineering research on scripting languages. Kernighan
remarked, “I think there’s been only minimal back and forth between scripting
languages and software engineering, though perhaps it’s increasing. Speaking
specifically for awk, there was no influence at all from any ‘software engineering’
perspective . . . as for the influence of scripting languages on software engineering, I don’t see much there either.” Thus, he declined to answer the questions
we posed.
ACM Transactions on Software Engineering and Methodology, Vol. 14, No. 4, October 2005.
464
•
B. G. Ryder et al.
In this section, excerpts from these interviews are presented, in roughly
chronological order of the language they designed, to show relevant influences
between software engineering research and programming languages, as recalled by the language designers.
Professor Boris Magnusson (Simula 67):
Professor Magnusson has personal knowledge of the early days of Simula
67. We were grateful for his participation, especially given the recent untimely
deaths of Nygaard and Dahl, who jointly won the ACM Turing Award in 2001
for the development of Simula 67.
1. What were the problems that you were addressing in your design
for Simula 67? Complexity of large software systems. The experience behind
Simula 67 came from developing large discrete event simulation models, programs that indeed tend to get large, complex and involved. These models also
include a notion of concurrency, although it is not necessarily reflected in the
execution of the model.
2. What programming practices or software engineering research do
you think influenced your language design, positively or negatively?
The notion of a safe language inherited from Algol is perhaps in this category,
the strive to find trivial errors in a program, errors in respect to the language
definition, at an early stage. The inclusion of automatic garbage collection,
available in LISP systems at the time, was motivated by the same reason. Tony
Hoare’s work on record handling influenced the formation of the class concept.
[Ed. note: There is no separate response in this interview to question 3.]
4. Were there specific applications that drove your design? No! It
(Simula 67) is a general purpose programming language.
5. If you were to design a programming language today, how would
it differ from current programming languages? I would put more stress
on supporting building of notions of concurrency in the language. This point
is sadly missing in modern languages. Introducing ONE notion of concurrency
in a language, like Thread in Java, is too limiting. If you, for example, want to
write a program that animates a simulation, you need two different time bases
and scheduling mechanisms at the same time.
Professor Niklaus Wirth (Pascal, Modula):
Professor Wirth was awarded the ACM Turing Award in 1984 for developing
several innovative computer languages, including Modula and Pascal.
1. What were the problems that you were addressing in your design
for Pascal and Modula? Two purposes stood in the foreground: 1.To obtain a
language suitable for system programming. . . 2. To obtain a language suitable
for teaching the fundamentals of programming in a lucid, systematic manner,
without undue references to particular computers and implementations.
2. What programming practices or software engineering research do
you think influenced your language design, positively or negatively?
Software Engineering was not yet a subject of research; even the term did not
exist. Programming methods was the name of the subject. Of great influence to
Pascal was Structured Programming, put forth by E. W. Dijkstra. This method
of proceeding in a design would obviously be greatly encouraged by the use of a
ACM Transactions on Software Engineering and Methodology, Vol. 14, No. 4, October 2005.
The Impact of Software Engineering Research
•
465
Structured Language, a language with a set of constructs that could freely be
combined and nested. The textual structure of a program should directly reflect
its flow of control.
Another key idea stemmed from the fact that the computing profession was
split into scientific computing and commercial data processing, and from my
attempt to unify their bases . . . . Of negative influence was the need to win programmers for a new language. This need forced me to retain constructs and
facilities that programmers were used to and did not want to miss, although I
knew they would have to be left out in the interest of safer programming. Examples are the go to statement, the variant record (data overlay), and incomplete
parameter type specification.
3. Can you recollect any of the papers you were reading, the conferences you were attending and the people you were talking to when you
were designing Pascal and Modula? By far the biggest influence came from
the Report on Algol 60. My interest in programming languages was increased by
Prof. A. van Wijngaarden, who spent a sabbatical semester at Berkeley, where I
was working for my doctorate. I was brought in contact with the Algol Working
Group 2.1 of IFIP, and there the most influential colleagues were E. W. Dijkstra,
C. A. R. Hoare and P. Naur. We attended several work meetings and exchanged
many ideas, which first led to Algol W (1966, implemented at Stanford), then
to Pascal (1970, implemented in Zurich).
Modula-2 followed in 1979 as intended successor to Pascal, and it grew out of
the need to further develop Pascal to cater for the needs of large systems (software engineering). Several ideas came from the language Mesa (B. Lampson,
J. Mitchell, J. Morris, Ch. Geschke), to which I was introduced during a sabbatical year at the Xerox Palo Alto Research Center in 1976/7. My main contribution was (as to some extent also in the case of Pascal) combining, molding
all constructs into a single, harmonious framework, and in simplifying them,
extracting the essentials and discarding the bells and whistles.
4. Were there specific applications that drove your design? In the case
of Pascal, the need for a decent language for teaching and for system programming. In the case of Modula-2, the need for a language adequate for modular
system building, and the desire to finally get rid of antiquated constructs (such
as go to).
5. If you were to design a programming language today, how would
it differ from current programming languages? If you mean Java and
C# by current languages, then my answer is: Look at Oberon (1988). Most of
their features had been present in Oberon, my successor to Modula-2, some
7–10 years earlier. The chief difference to Java and C# is its size, in terms of
number of syntactic rules, of number of pages of definition, and in the size of its
compilers. The Report was only 16 pages long, and the entire Oberon compiler
took about 45 Kbyte, was very efficient, and due to its transparency, highly
reliable. Oberon was Modula-2 with object-orientation.
The sad thing about new developments is that they always seem to turn
out more complex rather than simpler. Yet it is known that progress in (mathematical) sciences had mostly been through simplification and unification of
concepts.
ACM Transactions on Software Engineering and Methodology, Vol. 14, No. 4, October 2005.
466
•
B. G. Ryder et al.
Dr. Jean Ichbiah (Ada):
Dr. Ichbiah was the principal designer of Ada.
[Ed. note: There is no separate response in this interview to question 1.]
2. What programming practices or software engineering research do
you think influenced your language design, positively or negatively?
Doing programming language design in the mid-1970s, we were addressing a
set of objectives derived from software engineering, definitely. These were the
years when hardware prices were coming down significantly and machines were
becoming much cheaper. It was possible to run much larger applications, but
previous programming methods didn’t scale. It was like constructing a small
hut versus a skyscraper. Trying to scale methods of developing programs was
difficult; the costs were increasing in exponential fashion rather than linearly
with program size. . . we learned how to scale with linear cost, by introducing
modularization and packaging.
Dijkstra had a profound idea, that programs should become closer to text.
If you could read a program and understand it, then it was a good program.
You should be able to read a program like a book; this was a notion of linearity.
The initial ideas were expressed in Dijkstra’s Go tos considered harmful paper,
but this title was a misnomer. Dijkstra was laying the foundation of how to
understand a program through linear thinking. Twenty-five years later we can
see the absolute necessity for this idea, that the complexity of code be linear in
its size. This was essential to allow systems to grow in size. The key emphases
were to make programs readable, maintainable, and reliable. Readability is by
far the more important issue as it controls the other two.
Dijkstra saw an infinite space of possible programs and used a constructive
approach to extract an infinite subset of programs that you can read easily
and can convince yourself that they are correct. . . . As an example of this in
the design of Ada, I am proud of the textual separation of specification and
implementation, as it lets you know what you need to know to use a module,
without getting into details of implementation.
We systematically designed PL features in a manner like structural engineering; that is, we would look for failure patterns and then try to make something
that would not break.
3. Can you recollect any of the papers you were reading, the conferences you were attending and the people you were talking to when you
were designing Ada? There were several working groups that met several
times a year. Two were the IFIP Working Group 2.4 on System Implementation
Languages [IFIP 2004] and the Purdue Europe LTPL-E committee. There was
a conference on system implementation languages in 1973 or 1974 in Trondheim. This was a not too big conference and at its end, about 10 researchers
met and formed an IFIP working group that provided collegial feedback and
stimulation to participants about 3–4 times a year. Participants included Bill
Wulf and Jim Horning. Another influential group was the IFIP 2.3 group on
Algorithmics. These groups gave researchers a chance to meet multiple times a
year, present what they were working on and to discuss it with peers who could
comment and criticize.
ACM Transactions on Software Engineering and Methodology, Vol. 14, No. 4, October 2005.
The Impact of Software Engineering Research
•
467
4. Were there specific applications that drove your design? The Ada
PL was fairly general, however one new aspect it addressed was real-time programming. The metaphor used at the time, to talk about applications that would
use this new paradigm, was to think of airplanes as software with wings. Another new aspect of computing addressed by Ada was programs designed to be
executed on distributed computers.
5. If you were to design a programming language today, how would
it differ from current programming languages? If I were to design Ada
today, it would not be much different in a way. I would try to make it even
simpler. Although I do not want to design another PL now, I would take Ada
and trim it. For example, I would eliminate parameterized types (i.e., variant
records) Generics also appear in Ada but may be less useful than originally
thought . . . . Inheritance seems to me to be a low-level concept; this is a detail
of implementation rather than a conceptual thing.
When we were inventing modularity in the 1970s, we were solving the problem of scalability. This resulted in making software that scales linearly. Now
there is a full industry of components that uses this philosophy, across many
programming languages. Improvements in programming languages today are
second order effects.
Dr. Bjarne Stroustrup (C++):
Dr. Stroustrup was the designer and original implementor of C++.
1. What were the problems that you were addressing in your design for C++? Initially, I simply needed a tool to help me with a project
to distribute the Unix kernel across multiple machines. I saw two areas of
need: To express the logical partitions within the kernel code (the kernel
was—and is—written in C, and C doesn’t provide facilities for directly representing logical partitions and their communication paths) and to write simulations to determine the effects of different communication patterns resulting from different software configurations and different types of hardware
support.
2. What programming practices or software engineering research do
you think influenced your language design, positively or negatively?
Ideas for operating system organization and application building, which I was
exposed to at Cambridge (notably the CAP computer and its use of hardware
protection) and Newcastle (the C++ notion of exceptions and their use) was
directly inspired by the work on reliable systems by Brian Randell’s group.
The “object-oriented” ideas from Simula 67, and appreciation of static type
checking from Simula 67 and Algol 68 (this appreciation wasn’t widely shared
among people building operating system kernels).
3. Can you recollect any of the papers you were reading, the conferences you were attending and the people you were talking to when you
were designing C++? I went to SIGOPS, USENIX, and a distributed systems
conference. . . . However, my main influence was my colleagues in the Bell Labs
Computer Science Research Center, including Sandy Fraser, Steve Johnson,
Brian Kernighan, Doug McIlroy, Bob Morris, Gregg Chesson, Stu Feldman,
Dennis Ritchie, and Steve Bourne. This was in the very early years where the
ACM Transactions on Software Engineering and Methodology, Vol. 14, No. 4, October 2005.
468
•
B. G. Ryder et al.
key notions of C++ were formed. I think that it is significant that the systems
people dominated over the language people.
4. Were there specific applications that drove your design? It started
with the distributed operating system kernel, which I never completed, and
the simulations. For years after, my bread and butter work in the Labs related
to various forms of simulation (network traffic, telephone use, board layout,
processor register design, etc.). I also worked with embedded systems and a
variety of systems programming tasks. I remember that the application that
finally caused me to introduce operator overloading wasn’t the obvious mathematical uses of operators, but modeling of bits, registers, and signals in a
processor design.
At the time, the UNIX system and networking loomed large in the collective
imagination of the Lab, as did telecommunications applications (not just huge
switching applications, but also small switches, embedded control applications,
and hand-held gadgets usually weighing a few pounds). In the 1980s, Bell Labs
was an environment very rich in diverse real-world applications and people
with both research training and real-world experience.
5. If you were to design a programming language today, how would
it differ from current programming languages? A language design—like
all design—should arise from a need. I don’t clearly see a problem with current
programming practice that would best be solved by a new language. Note that
when I designed C++, I based it on an existing language, C, to build on existing
strengths to have a complete and useful tool very early on. Should I design
another language, I’d probably do something similar again.
Dennis Canady (Visual Basic):
Dennis Canady was a member of the original Microsoft Visual Basic design
team.
1. What were the problems that you were addressing in your design
for Visual Basic? Visual Basic was shaped during the emergence of Windows.
Since Windows itself was just emerging, there naturally weren’t many Windows
applications, but applications are needed to make an O/S useful. So, we wanted
to make Windows applications easy to write. For one thing, we wanted an interactive development environment in which the performance of the language
would be similar to that of compiled code, but that would have the interactivity
and other nice features that come from an interpreted environment. Another
goal was to give developers of business applications a way to develop Windows
applications without having to write all that window-oriented code by hand.
2. What programming practices or software engineering research do
you think influenced your language design, positively or negatively?
Interactive debugging practices were an influence. In fact, Visual Basic’s design
was influenced by our desire for an execution model that could allow a good
interactive debugging environment. For example, we wanted to provide quick
feedback about syntax errors, and to point to identifiers in the source. Turbo
Pascal came out about that time, and had an influence on our design. Forth was
also an influence, which led to a threaded P-code interpreter. Of course, other
versions of Basic, including QuickBasic and Microsoft’s MacBasic, were also
ACM Transactions on Software Engineering and Methodology, Vol. 14, No. 4, October 2005.
The Impact of Software Engineering Research
•
469
influences. We also looked at visual programming languages, but at the time
most of them were dataflow-based, which did not seem like a good fit. I think we
saw ThinkPad, but not many other programming-by-demonstration languages.
Object models (C++, Ada, Smalltalk) were also influences. But creating an
application in Smalltalk was too large, too isolated from Windows, and too
slow. We asked “How can we do better?” Then Ruby came along [Ed note: this
was the code name for the visual programming language for Windows shell
programming mentioned in Section 4.2.]. We purchased the concept, and used
it for Visual Basic.
3. Can you recollect any of the papers you were reading, the conferences you were attending and the people you were talking to when you
were designing Visual Basic? I went to some OOPSLAs around that time. I
was also following the C++ world, and Bertrand Meyer’s work on Eiffel.
4. Were there specific applications that drove your design? Windows
business applications.
[Ed. note: There is no separate response in this interview to question 5.]
Tim Lindholm (Java):
Tim Lindholm is a Distinguished Engineer for the Java Software group at
Sun Microsystems. He was an original member of the Java project at Sun and
remains the architect of the Java virtual machine.
1. What were the problems that you were addressing in your design
for Java? The language that became known as Java was initially called Oak,
and was originally used for programming an embedded device, a sort of cross
between a large PDA and a super-duper remote control. The next use of Oak
was as the language for a video-on-demand project, the project in which I was
first involved. (Early in 1994, Lindholm joined the project.) When the market
for video-on-demand was created in 1994, a portion of the team went off to investigate how to use Oak as a safe way of deploying applications over the World
Wide Web. It is interesting that in the design of Oak, programming language
concepts were selected that had in some cases been around for 20 years. Even
so, the first two applications of the technology went nowhere. . . One of the main
goals of Oak was to enable programs to safely move around a network of heterogeneous computational units. When moving Oak to the Web the team added
a small number of key technical innovations, among them class loaders and
verification of program type safety. . . . Then known as Java, the language hit
the wave of popularity just right: while HTML could be downloaded to browsers
on various machines, it only provided static content; Java applets could make
Web content dynamic, and people grokked the idea. . . . There were 2 million
people working with HTML and considering themselves to be programming
the Internet. At that point we offered them Java as a power tool. . . .
2. What programming practices or software engineering research do
you think influenced your language design, positively or negatively?
At this time, people were starting to be upset with C++ because it was hard to
write programs you could understand and it was not safe, compiling to platformspecific executable code. Gosling called Java, C++ without guns and knives. The
Sun team could not use C++ for the applications they needed to write. When
ACM Transactions on Software Engineering and Methodology, Vol. 14, No. 4, October 2005.
470
•
B. G. Ryder et al.
asked “Why was C++ inadequate?” he replied, C++ programs compiled to native binaries, which made it impossible to safely move them about the Internet,
and at least hard to make them run on different architectures. Also, we felt
that C++ was sufficiently hard to program in that less-skilled programmers,
who we hoped to reach, would have difficulty with it.
Software engineering practices that influenced us included many objectoriented ideas, as expressed in C++ and Smalltalk-80. Java designers need to
give credit to folks who developed other object-oriented languages, from whom
they borrowed ideas.
3. Can you recollect any of the papers you were reading, the conferences you were attending and the people you were talking to when you
were designing Java? The people I was talking to were pretty much within
this group at SUN in 1994. There were 30 in the video-on-demand group. Of
these about 12 of us worked on the Java that people would currently recognize.
Between July and December of 1994 we wrote WebRunner, a browser that ran
Oak applets. . . . It is true to some degree that we went into a back room and
designed the language. We had problems to solve that directed our work. We
didn’t design this by committee or opinion poll. We took unto ourselves as working programmers, to answer the question: What is it that we want? We were
designing a language for ourselves to use.
[Ed. note: In a later communication, Lindholm acknowledged that “the Oak
team did have a lot of highly experienced language designers and implementors
who were very aware of the computer science literature.”]
4. Were there specific applications that drove your design? Specifically we were targeting applications for the Internet to run on browsers. But
we were aware that the properties of the language we were designing would be
much more broadly usable.
5. If you were to design a programming language today, how would
it differ from current programming languages? I am leery of objectorientation as a kind of religion that drags in complexity in the guise of simplicity. It bugs me that sometimes to use an object system requires mind-twisting
discussions on what things mean. Real programmers don’t have time for religious arguments. Nonetheless I would like to see the world take another run at
a Smalltalk-like language, something simpler than current popular languages.
Java was striving for elegance and simplicity while retaining familiarity and
usability. For example, Gosling went against the grain, and refused to put stuff
into Java, such as operator overloading, which makes the language harder
to learn and makes it easier to make mistakes in programming. Now that
the world is more comfortable with garbage collection, threads, and virtual
machines, it would be desirable to try another programming language (like
Smalltalk) where more cleanliness and elegance are embodied.
Tucker Taft (Ada 95):
Tucker Taft was chief language designer of Ada 95.
1. What were the problems that you were addressing in your design
for Ada 95? In general, Ada 83 was viewed as a “static” and somewhat “closed”
language. Our goal for Ada 95 was to make the language more flexible, more
ACM Transactions on Software Engineering and Methodology, Vol. 14, No. 4, October 2005.
The Impact of Software Engineering Research
•
471
extensible, and easier to interface with the outside world, be it subsystems
written in other languages, external hardware devices, or underlying operating
systems. At the same time, we wanted to preserve Ada 83’s strong focus on
safety, reliability, and readability, and its excellent support for ‘programming
in the large’ thanks to its very strong type checking.
2. What programming practices or software engineering research do
you think influenced your language design, positively or negatively?
The big jump for Ada 95 was to incorporate the thinking on inheritance and
polymorphism (i.e., object-oriented programming). One of our challenges was to
provide the dynamic extensibility of inheritance and polymorphism, without the
negatives of strong coupling that inheritance can create between a base type and
a derived type. . . . The point is that we were very concerned with the software
engineering aspects of our design choices. Whether we could point to specific
“research” that was critical to our work, that would be harder. But generally
the principles that were developed in the software engineering community were
very important.
3. Can you recollect any of the papers you were reading, the conferences you were attending and the people you were talking to when
you were designing Ada 95? At a high level, I would say that the Ada 9X design team was unusually aware of the computer science literature, and formal
verification literature, as well as software engineering principles. I would not
say we were avid readers of software engineering research. In fact, I would say
we more often bemoaned the lack of real research into the software engineering
advantages or disadvantages of particular language design choices. We had to
rely on our own experience and gedanken experiments more than we would
have liked.
I attended OOPSLA a few times. I also read a number of papers relating to
modular thread synchronization mechanisms. Some of this was pretty old stuff,
such as Concurrent Pascal. Other articles were more recent, such as work on a
language called Orca. All of these had various twists on the notion of a monitor.
We ultimately ended up with something called “Protected Types” which combine
the guards of Ada 83’s rendezvous (which were in turn inspired by CSP), with
the passivity of monitors. From a software engineering point of view, I (humbly)
think protected types were a great synthesis of old and new ideas.
4. Were there specific applications that drove your design? Very large
applications; real-time applications; embedded applications. But in addition,
Ada 83 had emerged as one of the most widely used languages for teaching
programming in college. Because of that, there was a desire to lower the entry
barrier to the first time user. So there was also a desire to make it easier to
write short programs in Ada 95 that did something useful in a typical desktop
environment, so we added more features for dealing with things like command
line arguments (not usually relevant in embedded or real-time applications),
simplified I/O, etc.
5. If you were to design a programming language today, how would
it differ from current programming languages? I still feel there is a lot of
research worth doing on the relative productivity and error rates for languages
with different features or philosophies. But I realize this is difficult research to
ACM Transactions on Software Engineering and Methodology, Vol. 14, No. 4, October 2005.
472
•
B. G. Ryder et al.
do. I think most people agree about the fundamental goodness of abstraction,
modularity, information hiding, and encapsulation. But we certainly don’t all
seem to agree about how that should translate into particular language features. I also think there is an important aspect of language design that has not
been talked about much, and that is the “human engineering” of languages. . . .
By human engineering I mean whether the language is error prone in various
ways.
[Ed. note: Taft continued with a critique of several design decisions in two
current languages, C# and Java.]
I was pretty disappointed in Java. It has been a roaring commercial success,
but from a language design point of view, it took a lot of steps backward. They
dropped enumeration types, which makes absolutely no sense to me from a
software engineering point of view. People of course reinvent them, but they
are back to the bad old days of defining named constants, with no compiler
support, and no type checking. . . . The other big step backward for Java was
eliminating the separation of specification from implementation.
The language C# actually seems better than Java in some of these
respects. . . . I think C# took a step back relative to Java (and a big step back relative to Ada) in relegating thread synchronization support to a class, rather than
building the concurrency primitives into the language. Java at least has automatic locking/unlocking as part of making a synchronized method call. Relying
on the programmer to balance their lock/unlock calls is very error prone. Ada
goes further and provides significant task safety and coordination guarantees
through the use of guards in protected types. This sort of thing is very difficult
to accomplish using a thread class with concurrency primitives available as a
set of methods like lock, unlock, and wait.
6. SUMMARY
Programming language features such as exceptions, procedural and data abstraction, and types present evidence of the strong ties between software engineering and programming language research (and practice). Individuals who
have worked in both areas tie them together as well as the attention paid by both
communities to relevant research in the other community, attested to by their
references to this work in their own papers and presentations at each others’
conferences. Cotemporality of developments likewise attests to the influences
of these fields on one another.
It is perhaps unsurprising that this symbiosis exists between programming
languages and software engineering, with regard to software reliability research and exceptions, whose purpose is to provide programmer direction for
unusual (but anticipatable) circumstances. Similarly, software engineering research in modularity and reuse dovetails nicely with programming language
design emphasis on control and data abstraction, which evolved into inheritance with visibility controls. Likewise, strong typing can be seen as a response
to the emphasis on software reliability; somewhat later, user-defined types
and generics, are mechanisms to provide for software reuse. In addition, software engineering research on visual programming influenced modern end-user
ACM Transactions on Software Engineering and Methodology, Vol. 14, No. 4, October 2005.
The Impact of Software Engineering Research
•
473
programming languages, which use visual expressions to allow nonexperts to
create programs in specific domains. Finally, the oral histories demonstrate the
specific influences of software engineering research (i.e., goals and techniques
developed) as well as previous programming languages, on modern programming language design.
ACKNOWLEDGMENTS
We are most grateful to Carlo Ghezzi for reading several drafts of this
manuscript which led to an improved article. We also appreciate the contributions of Daniel Berry, Richard P. Gabriel, Bill Harrison, Andy Koenig, Barbara
Liskov, Mike Mahoney, Mary Shaw, and Charles Weisert, their suggestions and
comments. We also wish to thank the other members of the IMPACT Project
team for their support of our research. Finally, we thank the anonymous reviewers for their helpful comments.
REFERENCES
ACMCS. 1989. ACM Comput. Surv., volume 21, issue 3.
AMBLER, A. L. AND BURNETT, M. M. 1989. Influence of visual technology on the evolution of language environments. Computer 22, 10 (Oct.), 9–22.
ARNSON, R., ROSEN, D., WAITE, M., AND ZUCK, J. 1992. The Visual Basic How-To. The Waite Group
Press.
BAROTH, E. AND HARTSOUGH, C. 1995. Visual programming in the real world. In Visual ObjectOriented Programming: Concepts and Environments, M. Burnett, A. Goldberg, and T. Lewis,
Eds. Prentice Hall, Manning Publications, and IEEE.
BASILI, V. R., SELBY, R. W., AND HUTCHENS, D. H. 1986. Experimentation in software engineering.
IEEE Transactions Softw. Eng. 12, 7 (July), 733–743.
BERGIN, JR., T. AND GIBSON, JR., R. G., EDS. 1996. History of Programming Languages II. ACM
Press and Addison-Wesley Company.
BIRTWISTLE, G. 1973. SIMULA BEGIN. Studentlitterature and Auerback Publishing, Inc., Lund,
Sweden and Philadelphia, PA.
BOEHM, B. W. 1976. Software enginering. IEEE Trans. Comput. C-25, 12 (Dec.), 1226–1241.
BORNING, A. 1981. The programming language aspects of thinglab, a constraint–oriented simulation laboratory. ACM Trans. Prog. Lang. Syst. 3, 4 (Oct.), 353–387.
BOTTONI, P., COSTABILE, M. F., LEVIALDI, S., AND MUSSIO, P. 1997. From visual language specification
to legal visual interaction. In 1997 IEEE Symposium on Visual Languages. 234–241.
BRON, C., FOKKINGA, M., AND HAAS, A. 1975. A proposal for dealing with abnormal termination of
programs. Tech. Rep. Mem 150, Twente University of Technology. November.
BURNETT, M., BAKER, M., BOHUS, C., CARLSON, P., YANG, S., AND VAN ZEE, P. 1995. Scaling up visual
programming languages. Computer 28, 3 (Mar.), 45–54.
BURNETT, M. AND MCINTYRE, D. 1995. Visual programming. Computer 28, 3 (March), 14–16.
BURNETT, M., PENDSE, C. C. O., ROTHERMEL, G., SUMMET, J., AND WALLACE, C. 2003. End–user software engineering with assertions in the spreadsheet paradigm. In International Conference on
Software Engineering. 93–103.
CARDELLI, L. AND WEGNER, P. 1985. On understanding types, data abstraction and polymorphism.
ACM Comput. Surv. 17, 4 (Dec.), 471–522.
CARGILL, T. A. 1993. The case against multiple inheritance in C++. 101–109.
CHANG, S.-K., TAUBER, M. J., YU, B., AND YU, J.-S. 1989. A visual language compiler. IEEE Trans.
Softw. Eng. 15, 5 (May), 506–525.
COLLINS, A. M. AND QUILLIAN, M. 1969. Retrieval time for semantic memory. J. Verb. Learn. Verb.
Behav. 8, 240–247.
COOPER, A. 1996. Why I am called ‘the father of Visual Basic’. http://www.cooper.com. Accessed
December 26, 2002.
ACM Transactions on Software Engineering and Methodology, Vol. 14, No. 4, October 2005.
474
•
B. G. Ryder et al.
COURTOIS, P. J., HEYMANS, F., AND PARNAS, D. L. 1971. Concurrent control with rreaderss and
rwriterss. Comm. ACM 14, 10, 667–668.
COX, P. T., GILES, F. R., AND PIETRZYKOWSKI, T. 1989. Prograph: A step towards liberating programming from textual conditioning. In 1989 IEEE Workshop on Visual Languages. 150–156.
CRIMI, C., GUERCIO, A., PACINI, G., TORTORA, G., AND TUCCI, M. 1990. Automating visual language
generation. IEEE Trans. Softw. Eng. 16, 10 (Oct.), 1122–1135.
DAHL, O. AND NYGAARD, K. 1967. SIMULA 67 common base definition. Tech. rep., Norwegian
Computing Center.
DAHL, O.-J., DIJKSTRA, E. W., AND HOARE, C. 1972. Structured Programming. Academic Press.
DIJKSTRA, E. 1969. Structured programming. In Software Engineering Techniques: Report on a
Conference sponsored by the NATO Science Committees, J. Buxton and B. Randell, Eds. Rome,
Italy, 84–88.
DIJKSTRA, E. W. 1965. Solution of a problem in concurrent programming control. Comm. ACM 8, 9
(Sept.), 569.
DIJKSTRA, E. W. 1968a.
Cooperating sequential processes. In Programming Languages,
F. Genuys, Ed. Academic Press, 43–112.
DIJKSTRA, E. W. 1968b. Go to statement considered harmful. Comm. ACM 11, 3, 147–148.
DOD, U. 1980. Reference manual for the Ada programming language. In DOD. New York.
ELLIS, M. A. AND STROUSTRUP, B. 1990. The Annotated C++ Reference Manual. Addison-Wesley
Publishing.
FRANKEL, M. 1993. Enabling reuse with Ada generics. In Proceedings of the Tenth Annual
Washington Ada Symposium on Ada’s Role in Software Enginering, McClean, VA, 17–30.
GANNON, J. 1977. An experimental evaluation of data type conventions. Comm. ACM 20, 8, 584–
595.
GANNON, J. AND HORNING, J. 1975. Language design for programming reliability. IEEE Trans.
Softw. Eng. SE-1, 2 (June), 179–191.
GHEZZI, C. AND JAZAYERI, M. 1998. Programming Language Concepts. John Wiley & Sons.
GLINERT, E. P. AND TANIMOTO, S. L. 1984. Pict: An interactive graphical programming environment.
Computer 17, 11 (Nov.), 7–25.
GOLDBERG, A. 1984. Smalltalk–80: The Interactive Programming Environment. Addison-Wesley.
GOLDBERG, A. AND ROBINSON, D. 1983. Smalltalk-80: the Language and Implementation. AddisonWesley, Reading, MA.
GOODENOUGH, J. B. 1975a. Exception handling: Issues and a proposed notation. Comm.
ACM 18, 12 (Dec.), 683–696.
GOODENOUGH, J. B. 1975b. Structured exception handling. In Conference Record of the Second
Annual ACM SIGACT/SIGPLAN Symposium on Principles of Programming Languages. 204–
224.
GOSLING, J., JOY, B., AND STEELE, JR., G. L. 1996. The Java Language Specification. Addison-Wesley,
Reading, MA.
GRAVER, J. O. AND JOHNSON, R. E. 1990. A type system for Smalltalk. In Conference Record of the
17th Annual ACM SIGACT/SIGPLAN Symposium on Principles of Programming Languages.
136–150.
GREEN, T. AND PETRE, M. 1996. Usability analysis of visual programming environments: A ‘cognitive dimensions’ framework. J. Vis. Lang. Comput. 7, 2 (June), 131–174.
GUTTAG, J. V., HORNING, J. J., AND WING, J. M. 1985. The Larch family of specification languages.
IEEE Softw. 2, 5 (Sept.), 24–36.
HABERMANN, A. AND NOTKIN, D. 1986. Gandalf software development environment. IEEE Trans.
Softw. Eng. SE-12, 12 (Dec.), 1117–1127.
HABERMANN, A. N. 1973. Critical comments on the programming language Pascal. Acta Informatica 3, 47–57.
HANSEN, P. B. 1972. Structured multiprogramming. Comm. ACM 15, 7 (July), 574–578.
HANSEN, P. B. 1975. The programming language concurrent Pascal. IEEE Trans. Softw. Eng. 1, 2,
199–207.
HANSEN, P. B. 1996. Monitors and concurrent Pascal: A personal history. In History of Programming Languages-II, T. Bergin and R. Gibson, Eds. Addison-Wesley, 121–172.
HARBISON, S. P. 1992. Modula-3. Prentice Hall.
ACM Transactions on Software Engineering and Methodology, Vol. 14, No. 4, October 2005.
The Impact of Software Engineering Research
•
475
HELM, R., MARRIOTT, K., AND ODERSKY, M. 1991. Building visual language parsers. In ACM Conference on Human Factors in Computing Systems. 105–112.
HIRAKAWA, M., TANAKA, M., AND ICHIKAWA, T. 1990. An iconic programming system, hi-visual. IEEE
Trans. Softw. Eng. 16, 10 (Oct.), 1178–1184.
HOARE, C. 1969. An axiomatic approach to computer programming. Comm. ACM 12, 10 (Oct.),
576–580, 583.
HOARE, C. 1974a. Hints on programming language design. In State of the Art Report 20: Computer Systems Reliabilty, C. Bunyan, Ed. Pergamon/Infotech. This paper originated in a keynote
address at the ACM SIGPLAN POPL conference in Boston in October 1973 and although it was
not in the proceedings, it was distributed at the conference. A 1989 collection of Dr. Hoare’s essays
entitled Essays in Computing Science published by Prentice Hall, also contains a reprint of this
paper.
HOARE, C. 1974b. Monitors: An operating systems structuring concept. Comm. ACM 17, 10
(Oct.), 549–557.
HOARE, C. 1978. Communicating sequential processes. Comm. ACM 21, 8 (Aug.), 666–677.
HOPKINS, M. E. 1972. A case for the goto. In Proceedings of the 25th National ACM Conference.
787–790.
HORNING, J. J. 1979. Programming languages. In Computing Systems Reliability, T. Anderson
and B. Randell, Eds. Cambridge University Press, 109–152.
HOROWITZ, E. AND MUNSON, J. G. 1984. An expansive view of reusable software. Trans. Softw.
Eng. SE-10, 5 (Sept.), 477–487.
ICHBIAH, J., HELIARD, J., ROUBINE, O., BARNES, J., KREIG-BRUECKNER, B., AND WICHMANN, B. A. 1979.
Rationale for the design of the ADA programming language. ACM SIGPLAN Notices 14, 6 (June),
1–261.
IEEESW 1989. IEEE Software, issue on parallel programming.
IFIP 2004. http://www.mlaa.com.au/IFIPWG2.4/index.htm.
INGALLS, D. 1978. The Smalltalk-76 programming system: Design and implementation. In Conference Record of the Fifth Annual ACM Symposium on Principles of Programming Languages.
9–16.
KEFFER, T. 1995. Programming with the standard template library, sage advice for coping with
the stl. Dr. Dobb’s Journal 1995, SI3.
KICZALES, G., LAMPING, J., MENDHEKAR, A., MAEDA, C., LOPES, C. V., LOINGTIER, J.-M., AND IRWIN, J.
1997. Aspect-oriented programming. In Proceedings of the European Conference on Objectoriented Programming (ECOOP). Springer-Verlag LNCS 1241.
KOENIG, A. AND STROUSTRUP, B. 1993. Exception handling for C++. In The Evolution of C++:
Language Design in the Marketplace of Ideas, J. Waldo, Ed. MIT Press. a USENIX Association
book.
LIBRARY, I. S. R. 1970. IBM System/360 Operating System PL/I (F) Language Reference Manual.
4th edition.
LIPPERT, M. AND LOPES, C. V. 2000. A study on exception detection and handling using aspectoriented programming. In Proceedings of the 22nd International Conference on Software Engineering. 418–427.
LISKOV, B. 1993. A history of CLU. In Proceedings of History of Programming Languages Conference (ACM SIGPLAN Notices, vol. 28, no. 3). 133–147.
LISKOV, B. AND GUTTAG, J. 1986. Abstraction and Specification in Program Development. MIT Press
and McGraw-Hill Book Company.
LISKOV, B. AND SNYDER, A. 1979. Exception handling in CLU. IEEE Trans. Softw. Eng. SE-5, 6
(Nov.), 546–558.
LISKOV, B., SNYDER, A., ATKINSON, R., AND SCHAFFERT, J. 1977. Abstraction mechanisms in CLU.
Comm. ACM 20, 8, (Aug.), 564–576.
LISKOV, B. AND ZILLES, S. 1974. Programming with abstract data types. In ACM SIGPLAN Conference on Very High Level Languages. 50–59.
LISKOV, B. AND ZILLES, S. 1975. Specification techniques for data abstractions. IEEE Trans. Softw.
Eng. SE-1, 7–19.
LISKOV, B. H. 1972. A design methodology for reliable software systems. In Proceedings of the
Fall Joint Computer Conference. 191–198.
ACM Transactions on Software Engineering and Methodology, Vol. 14, No. 4, October 2005.
476
•
B. G. Ryder et al.
LITKE, J. 1990. A systematic approach for implementing fault tolerant software designs in Ada.
In Proceedings of the Conference on TRI-Ada’90. 403–408.
LUCKHAM, D. C. AND POLAK, W. 1980. Ada exception handling: An axiomatic approach. ACM Trans.
Prog. Lang. Syst. 2, 2 (April), 225—233.
MACLAREN, M. D. 1977. Exception handling in PL/I. In Proceedings of the ACM Conference on
Language Design for Reliable Software. 101–104.
MADSEN, O. L., MAGNUSSON, B., AND MOLLER-PEDERSEN, B. 1990. Strong typing of object-oriented
languages revisited. In Proceedings of the European Conference on Object-oriented Programming
(ECOOP). 140–151.
MCCARTHY, J., ABRAMS, P. W., EDWARDS, D. J., HART, T. P., AND LEVIN, M. 1965. LISP 1.5 Programmer’s
Manual. MIT Press.
MCILROY, D. 1976. Mass-produced software components. In Software Engineering Concepts and
Techniques, 1968 NATO Conference on Software Engineering, J. Buxton, P. Naur, and B. Randell,
Eds. 88–98.
MILLER, R. AND MYERS, B. 2001. Outlier finding: focusing user attention on possible errors. In
ACM User Interface Software and Technology. 81–90.
MURRAY, R. 1988. Building well-behaved type relationships in C++. In Proceedings of USENIX.
19–30.
MYERS, B. A. 1990. Creating user interfaces using programming by example, visual programming, and constraints. ACM Trans. Prog. Lang. Syst. 12, 2 (April), 143–177.
NYGAARD, K. AND DAHL, O.-J. 1978. The development of the SIMULA languages. In Proceedings
of the History of Programming Languages Conference, ACM SIGPLAN Notices, vol. 13, no. 8.
245–276.
PANE, J., MYERS, B., AND MILLER, L. 2002. Using hci techniques to design a more usable programming system. In IEEE Human–Centric Computing Languages and Environments. 198–206.
PARNAS, D. 1971. On the criteria to be used in decomposing systems into modules. Tech. Rep.
Department of Computer Science, Carnegie-Mellon University.
PARNAS, D. 1972. On the criteria to be used in decomposing systems into modules. Comm.
ACM 15, 2, 1053–1058.
PERRY, D. E. 1989. The inscape environment. In Proceedings of the 11th International Conference
on Software Engineering. 2–12. Selected as best paper from 10 years ago ICSE.
PLAUGER, P. L. 1995. Standard C/C++ the standard template library. C/C++ Users Journal 13, 12, 10–20.
POPEK, G., HORNING, J., LAMPSON, B., MITCHELL, J., AND LONDON, R. 1977. Notes on the design of
euclid. ACM Sigplan Notices 12, 3, 11–18.
PRIETO-DIAZ, R. 1993. Status report: Software reusability. IEEE Softw. 10, 3 (May), 61–66.
RADIN, G. 1981. The early history and characteristics of PL/I. In History of Programming Languages, R. L. Wexelblat, Ed. Academic Press, 551–600.
RANDELL, B. 1975. System structure for software fault tolerance. In Proceedings of the International Conference on Reliable Software. 437–439.
RAZ, O., KOOPMAN, P., AND SHAW, M. 2002. Semantic anomaly detection in online data sources. In
International Conference on Software Engineering. 302–312.
REDWINE, S. T. AND RIDDLE, W. E. 1985. Software technology maturation. In Proceedings of the 8th
International Conference on Software Engineering. 189–200.
REISS, S. 1984. Graphical program development with pecan program development systems. In
ACM SIGSOFT/SIGPLAN Symposium on Practical Software Development Environments.
ROBILLARD, M. P. AND MURPHY, G. C. 2000. Designing robust Java programs with exceptions. In
Proceedings of the 8th ACM SIGSOFT Symposium on Foundations of Software Engineering.
2–10.
ROSCHELLE, J., KOUTLIS, M., REPENNING, A., JACKIW, N., AND SUTHERS, D. 1999. Developing educational software components. Computer 32, 9 (Sept.), 50–58.
ROTHERMEL, G., LI, L., DUPUIS, C., AND BURNETT, M. 1998. What you see is what you test: A methodology for testing form-based visual programs. In International Conference on Software Engineering. 198–207.
ROWE, L. A. 1980. Data abstraction from a programming language viewpoint. In ACM Workshop
on Data Abstraction, Databases, and Conceptual Modeling.
ACM Transactions on Software Engineering and Methodology, Vol. 14, No. 4, October 2005.
The Impact of Software Engineering Research
•
477
ROWE, L. A., DEUTSCH, L. P., SHAW, M., THATCHER, J. W., MAYR, H. C., ZILLES, S. N., AND HAYES, P. J.
1980. Types (discussion). SIGMOD Record 11, 2, 43–52.
RUBIN, F. 1987. ’goto considered harmful considered harmful. Comm. ACM 30, 3, 195–196.
RUBIN, R. V., GOLIN, E. J., AND REISS, S. P. 1985. Thinkpad: A graphical system for programming
by demonstration. IEEE Softw. 2, 2 (Mar.), 73–79.
SCOTT, M. L. 2000. Programming Language Pragmatics. Morgan Kaufmann Publishers, San
Francisco, Ca.
SHAW, M. 1981. ALPHARD: Form and Content. Springer-Verlag, New York.
SHAW, M. 1984. Abstraction techniques in modern programming languages. IEEE Softw. 1, 4,
10–26.
SHAW, M. 2001. The coming-of-age of software architecture research. In Proceedings of the 23rd
International Conference on Software Engineering. 657–664.
SHAW, M., ALMES, G. T., NEWCOMER, J., REID, B., AND WULF, W. 1978. Comparison of programming
languages for software engineering. Tech. rep., Department of Computer Science, CMU.
SHAW, M., WULF, W. A., AND LONDON, R. L. 1977. Abstraction and verificiation is alphard: Defining
and specifying iteration and generators. Comm. ACM 20, 3, 553–564.
SMITH, D. C. 1977. Pygmalion: A Computer Program to Model and Stimulate Creative Thought.
Birkhauser.
STROUSTRUP, B. 1987. Possible directions for C++. In Proceedings of USENIX C++ Workshop.
STROUSTRUP, B. 1993. A history of C++: 1979–1991. In Proceedings of the History of Programming
Languages Conference (ACM SIGPLAN Notices, vol. 28, no. 3). 699–755.
SUTHERLAND, I. E. 1963. Sketchpad: A man–machine graphical communication system. In AFIPS
Spring Joint Computer Conference.
SUTHERLAND, W. 1966. On-line graphical specification of computer procedures. Tech. rep., MIT.
MIT Ph.D. Thesis.
TANENBAUM, A. S. 1976. A tutorial on Algol68. ACM Comput. Surv. 8, 2 (June), 155–190.
TEITELBAUM, T. AND REPS, T. 1981. The Cornell Program Synthesizer: A syntax-directed programming environment. Comm. ACM 24, 9 (Sept.), 563–573.
TEITELMAN, W. 1984. A tour through cedar. In ICSE ’84: Proceedings of the 7th International
Conference on Software Engineering. IEEE Press, Piscataway, NJ, USA, 181–195.
TGS SYSTEMS. 1990. Prograph Tutorial Manual. The Gunakara Sun Systems, Ltd. 2nd Printing,
July.
TICHY, W. F. 1998. Should computer scientists experiment more? 16 reasons to avoid experimentation. IEEE Comput. 31, 5 (May), 32–40.
VAN WIJNGAARDEN, A., MAILLOUX, B., PECK, J., KOSTER, C., SINTZOFF, M., LINDSEY, C., MEERTENS, L.,
AND FISKER, R. G. E. 1968.
Revised Report on the Algorithmic Langauge ALGOL68. Also appeared in ACM SIGPLAN Notices, Volume 12, Number 5, 1–70, May 1977; available online at
http://members.dokom.net/2.kloke/RR/rrTOC.html.
WALDO, J. 1991. The case for multiple inheritance in C++. Comput. Syst. 4, 1, 111–120.
WEGNER, P. 1984. Capital-intensive software technology. IEEE Softw. 1, 3 (July), 43–97.
WIRTH, N. 1971a. Program development by stepwise refinement. Comm. ACM 14, 2, 221–227.
WIRTH, N. 1971b. The programming language Pascal. Acta Informatica 1, 35–63.
WIRTH, N. 1977. Modula: A language for modular multiprogramming. Software Practice and
Experience 7, 3–35.
WULF, W., LONDON, R., AND SHAW, M. 1976. An introduction to the construction and verification of
alphard programs. IEEE Trans. Softw. Eng. SE-2, 4, 390.
WULF, W. AND SHAW, M. 1973. Global variable considered harmful. SIGPLAN Notices 8, 28–34.
WULF, W. A., RUSSELL, D. B., AND HABERMANN, A. N. 1971. Bliss: A language for systems programming. Comm. ACM 14, 12, 780–790.
Received September 2004; revised June and August 2005; accepted September 2005
ACM Transactions on Software Engineering and Methodology, Vol. 14, No. 4, October 2005.