15 1 Introduction 1 C H A P T E R 1 1 This book is concerned with programming languages. Programming languages, however, do not exist in a vacuum: they are tools for writing software. A comprehensive study of programming languages must take this role into account. We begin, therefore, with a discussion of the software development process and the role of programming languages in this process. Sections 1.1. through 1.5 provide a perspective from which to view programming languages and their intended uses. From this perspective, we will weigh the merits of many of the language concepts discussed in the rest of the book. Programming languages have been an active field of computer science for at least four decades. The languages that exist today are rooted in such historical developments, either because they evolved from previous versions, or because they derived inspiration from their predecessors. Such developments are likely to continue in the future. To appreciate this fragment of the history of science, we provide an overview of the main achievements in programming languages in Section 1.6. Finally, Section 1.7 provides an overview of the concepts of programming languages that will be studied throughout this book. This section explains how the various concepts presented in the remaining chapters fit together. 15

16 16 Introduction Chap Software development process From the inception of an idea for a software system, until it is implemented and delivered to a customer, and even after that, the software undergoes gradual development and evolution. The software is said to have a life cycle composed of several phases. Each of these phases results in the development of either a part of the system or something associated with the system, such as a fragment of specification, a test plan or a users manual. In the traditional waterfall model of the software life cycle, the development process is a sequential combination of phases, each having well-identified starting and ending points, with clearly identifiable deliverables to the next phase. Each step may identify deficiencies in the previous one, which then must be repeated. A sample software development process based on the waterfall model may be comprised of the following phases: Requirement analysis and specification. The purpose of this phase is to identify and document the exact requirements for the system.these requirements are developed jointly by users and software developers. The success of a system is measured by how well the software mirrors these stated requirements, how well the requirements mirror the users' perceived needs, and how well the users' perceived needs reflect the real needs. The result of this phase is a requirements document stating what the system should do, along with users' manuals, feasibility and cost studies, performance requirements, and so on. The requirements document does not specify how the system is going to meet its requirements. Software design and specification. Starting with the requirements document, software designers design the software system. The result of this phase is a system design specification document identifying all of the modules comprising the system and their interfaces. Separating requirements analysis from design is an instance of a fundamental what/how dichotomy that we encounter quite often in computer science. The general principle involves making a clear distinction between what the problem is and how to solve the problem. In this case, the requirements phase attempts to specify what the problem is. There are usually many ways that the requirements can be met. The purpose of the design phase is to specify a particular software architecture that will meet the stated requirements. The design method followed in this step can have a great impact on the quality of the resulting application; in particular, its understandability and modifiability. It can also affect the choice of the programming language to be used in system implementation. Implementation (coding). The system is implemented to meet the design specified in the previous phase. The design specification, in this case, states the what ; the goal of the implementation step is to choose how, among the many possible ways, the system shall be coded to meet the design specification. The result is a fully implemented and documented system. Verification and validation. This phase assesses the quality of the implemented system, which is then delivered to the user. Note that this phase should not be concentrated at

17 the end of the implementation step, but should occur in every phase of software development to check that intermediate deliverables of the process satisfy their objectives. For example, one should check that the design specification document is consistent with the requirements which, in turn, should match the user's needs. These checks are accomplished by answering the following two questions: Are we building the product right? Are we building the right product? Two specific kinds of assessment performed during implementation are module testing and integration testing. Module testing is done by each programmer on the module he or she is working on to ensure that it meets its interface specifications. Integration testing is done on a partial aggregation of modules; it is basically aimed at uncovering intermodule inconsistencies. Maintenance. Following delivery of the system, changes to the system may become necessary either because of detected malfunctions, or a desire to add new capabilities or to improve old ones, or changes that occurred in operational environment (e.g., the operating system of the target machine). These changes are referred to as maintenance. The importance of this phase can be seen in the fact that maintenance costs are typically at least as large as those of all the other steps combined. Programming languages are used only in some phases of the development process. They are obviously used in the implementation phase, when algorithms and data structures are defined and coded for the modules that form the entire application. Moreover, modern higher-level languages are also used in the design phase, to describe precisely the decomposition of the entire application into modules, and the relationships among modules, before any detailed implementation takes place. We will next examine the role of the programming language in the software development process by illustrating the relationship between the programming language and other software development tools in Section 1.2 and the relationship between the programming language and design methods in Section Languages and software development environments The work in any of the phases of software development may be supported by computer-aided tools. The phase currently supported best is the coding phase, with such tools as text editors, compilers, linkers, and libraries. These tools have evolved gradually, as the need for automation has been recognized. Nowadays, one can normally use an interactive editor to create a program and the file system to store it for future use. When needed, several previously created and (possibly) compiled programs may be linked to produce an executable program. A debugger is commonly used to locate faults in a program and eliminate them. These computer-aided program development tools have increased programming productivity by reducing the chances of errors. 17

18 18 Introduction Chap.1 Yet, as we have seen, software development involves much more than programming. In order to increase the productivity of software development, computer support is needed for all of its phases. By a software development environment we mean an integrated set of tools and techniques that aids in the development of software. The environment is used in all phases of software development: requirements, design, implementation, verification and validation, and maintenance. An idealized scenario for the use of such an environment would be the following. A team of application and computer specialists interacting with the environment develops the system requirements. The environment keeps track of the requirements as they are being developed and updated, and guards against incompleteness or inconsistency. It also provides facilities to validate requirements against the customer s expectations, for example by providing ways to simulate or animate them. The environment ensures the currency of the documentation as changes are being made to the requirements. Following the completion of the requirements, system designers, interacting with the environment, develop an initial system design and gradually refine it, that is, they specify the needed modules and the module interfaces. Test data may also be produced at this stage. The implementers then undertake to implement the system based on the design. The environment provides support for these phases by automating some development steps, by suggesting reuse of existing design and implementation components taken from a library, by recording the relationships among all of the artifacts, so that one can trace the effect of a change in say the requirements document to changes in the design document and in the code. The tools provided by the software development environment to support implementation are the most familiar. They include programming language processors, such as editors, compilers, simulators, interpreters, linkers, debuggers, and others. For this ideal scenario to work, all of the tools must be compatible and integrated with tools used in the other phases. For example, the programming language must be compatible with the design methods supported by the environment at the design stage and with the design notations used to document designs. As other examples, the editor used to enter programs might be sensitive to the syntax of the language, so that syntax errors can be caught before they are even entered rather than later at compile time. A facility for test data generation might also be available for programs written in the language. The above scenario is an ideal; it is only approximated by existing commer-

19 cial support tools, known under the umbrella term of CASE (Computer Aided Software Engineering), but the trend is definitely going into the direction of better support and more complete coverage of the process. 1.3 Languages and software design methods As mentioned earlier, the relationship between software design methods and programming languages is an important one. Some languages provide better support for some design methods than others. Older languages, such as FOR- TRAN, were not designed to support specific design methods. For example, the absence of suitable high-level control structures in early FORTRAN makes it difficult to systematically design algorithms in a top-down fashion. Conversely, Pascal was designed with the explicit goal of supporting topdown program development and structured programming. In both languages, the lack of constructs to define modules other than routines, makes it difficult to decompose a software system into abstract data types. To understand the relationship between a programming language and a design method, it is important to realize that programming languages may enforce a certain programing style, often called a programming paradigm. For example, as we will see, Smalltalk and Eiffel are object-oriented languages. They enforce the development of programs based on object classes as the unit of modularization. Similarly, FORTRAN and Pascal, as originally defined, are procedural languages. They enforce the development of programs based on routines as the unit of modularization. Languages enforcing a specific programming paradigm can be called paradigm-oriented. In general, there need not be a one-to-one relationship between paradigms and programming languages. Some languages, in fact, are paradigm-neutral and support different paradigms. For example, C++ supports the development of procedural and object-oriented programs. The most prominent programming language paradigms are presented in the sidebar on page 20. Design methods, in turn, guide software designers in a system s decomposition into logical components which, eventually, must be coded in a language. Different design methods have been proposed to guide software designers. For example, a procedural design method guides designers in decomposing a system into modules that realize abstract operations that may be activated by other procedural modules. An object-oriented method guides in decomposing a system into classes of objects. If the design method and the language para- 19

20 20 Introduction Chap.1 digm are the same, or the language is paradigm-neutral, then the design abstractions can be directly mapped into program components. Otherwise, if the two clash, the programming effort increases. As an example, an objectoriented design method followed by implementation in FORTRAN increases the programming effort. In general, we can state that the design method and the paradigm supported by the language should be the same. If this is the case, there is a continuum between design and implementation. Most modern high-level programming languages, in fact, can even be used as design notations. For example, a language like Ada or Eiffel can be used to document a system s decomposition into modules even at the stage where the implementation details internal to the module are still to be defined. sidebar start 1 Here we review the most prominent programming language paradigms, with special emphasis on the unit of modularization promoted by the paradigm. Our discussion is intended to provide a roadmap that anticipates some main concepts that are studied extensively in the rest of the book. Procedural programming. This is the conventional programming style, where programs are decomposed into computation steps that perform complex operations. Procedures and functions (collectively called routines) are used as modularization units to define such computation steps. Functional programming. The functional style of programming is rooted in the theory of mathematical functions. It emphasizes the use of expressions and functions. The functions are the primary building blocks of the program; they may be passed freely as parameters and may be constructed and returned as result parameters of other functions. Abstract data type programming. Abstract-data type (ADT) programming recognizes abstract data types as the unit of program modularity. CLU was the first language designed specifically to support this style of programming. Module-based programming. Rather than emphasizing abstract-data types, module-based programming emphasizes modularization units that are groupings of entities such as variables, procedures, functions, types, etc. A program is composed of a set of such modules. Modules can be used to define precisely which services are exported to the outside world by the module. In principle, any kind of service

21 can be provided by a module, not just the ability to generate and use abstract data. Modula-2 and Ada support this style of programming. Object-oriented programming. The object-oriented programming style emphasizes the definition of classes of objects. Instances of classes are created by the program as needed during program execution. This style is based on the definition of hierarchies of classes and run-time selection of units to execute. Smalltalk and Eiffel are representative languages of this class. C++ and Ada 95 also support the paradigm. Generic programming. This style emphasize the definition of generic modules that may be instantiated, either at compile-time or runtime, to create the entities data structures, functions, and procedures needed to form the program. This approach to programming encourages the development of high-level, generic, abstractions as units of modularity. The generic programming paradigm does not exist in isolation. It can exist jointly with object-oriented programing, as in Eiffel, with functional programming, as in ML. It also exists in languages that provide more than one paradigm, like Ada and C++. Declarative programming. This style emphasizes the declarative description of a problem, rather than the decomposition of the problem into an algorithmic implementation. As such, programs are close to a specification. Logic languages, like PROLOG, and rule-based languages, like OPS5 and KEE, are representative of this class of languages. sidebar end 1.4 Languages and computer architecture Design methods influence programming languages in the sense of establishing requirements for the language to meet in order to better support software development. Computer architecture has exerted influence from the opposite direction in the sense of restraining language designs to what can be implemented efficiently on current machines. Accordingly, languages have been constrained by the ideas of Von Neumann, because most current computers are similar to the original Von Neumann architecture (Figure 1). 21

22 22 Introduction Chap.1 I/O Memory CPU fetch instr. execute store result FIGURE 1. A Von Neumann computer architectur The Von Neumann architecture, sketched in Figure 1, is based on the idea of a memory that contains data and instructions, a CPU, and an I/O unit. The CPU is responsible for taking instructions out of memory, one at a time. Machine instructions are very low-level. They require the data to be taken out of memory, manipulated via arithmetic or logic operations in the CPU, and the results copied back to some memory cells. Thus, as an instruction is executed, the state of the machine changes. Conventional programming languages can be viewed as abstractions of an underlying Von Neumann architecture. For this reason, they are called Von Neumann languages. An abstraction of a phenomenon is a model which ignores irrelevant details and highlights the relevant aspects. Conventional programming languages keep their computation model from the underlying Von Neumann architecture, but abstract away from the details of the indivual steps of execution. Such a model consists of a sequential step-by-step execution of instructions which change the state of a computation by modifying a repository of values. Sequential step-by-step execution of language instructions reflects the sequential fetch and execution of machine instructions performed by hardware. Also, the variables of conventional programming languages, which can be modified by assignment statements, reflect the behavior of the memory cells of the computer architecture. Conventional languages based on the Von Neumann computation model are often called imperative languages. Other common terms are state-based languages, or statement-based languages, or simply Von Neumann languages. The historical developments of imperative languages have gone through increasingly higher levels of abstractions. In the early times of computing,

Chapter 1 1.1Reasons for Studying Concepts of Programming Languages a) Increased ability to express ideas. It is widely believed that the depth at which we think is influenced by the expressive power of

CSC 272 - Software II: Principles of Programming Languages Lecture 1 - An Introduction What is a Programming Language? A programming language is a notational system for describing computation in machine-readable

Appendix E Glossary of Object Oriented Terms abstract class: A class primarily intended to define an instance, but can not be instantiated without additional methods. abstract data type: An abstraction

Answer first, then check at the end. Review questions for Chapter 9 True/False 1. A compiler translates a high-level language program into the corresponding program in machine code. 2. An interpreter is

INTRODUCTION 1 Programming languages have common concepts that are seen in all languages This course will discuss and illustrate these common concepts: Syntax Names Types Semantics Memory Management We

Fundamentals of Java Programming This document is exclusive property of Cisco Systems, Inc. Permission is granted to print and copy this document for non-commercial distribution and exclusive use by instructors

The Role of Programming in Informatics Curricula A. J. Cowling Department of Computer Science University of Sheffield Structure of Presentation Introduction The problem, and the key concepts. Dimensions

Software Quality Issues when choosing a Programming Language C.J.Burgess Department of Computer Science, University of Bristol, Bristol, BS8 1TR, England Abstract For high quality software, an important

Announcements Programming Languages! Monday evening GBA section has been shut down " If you were assigned to this section, please find a different section " If you cannot attend a different section, please

Software Processes Objectives To introduce software process models To describe three generic process models and when they may be used To describe outline process models for requirements engineering, software

Functional Decomposition Top-Down Development The top-down approach builds a system by stepwise refinement, starting with a definition of its abstract function. You start the process by expressing a topmost

Java Application Developer Certificate Program Competencies After completing the following units, you will be able to: Basic Programming Logic Explain the steps involved in the program development cycle

Module 1 Introduction to Software Engineering Lesson 2 Structured Programming Specific Instructional Objectives At the end of this lesson the student will be able to: Identify the important features of

Division of Mathematical Sciences Chair: Mohammad Ladan, Ph.D. The Division of Mathematical Sciences at Haigazian University includes Computer Science and Mathematics. The Bachelor of Science (B.S.) degree

Compiling Object Oriented Languages What is an Object-Oriented Programming Language? Last time Dynamic compilation Today Introduction to compiling object oriented languages What are the issues? Objects

Interpreters and virtual machines Michel Schinz 2007 03 23 Interpreters Interpreters Why interpreters? An interpreter is a program that executes another program, represented as some kind of data-structure.

Software Engineering Architectural Design 1 Software architecture The design process for identifying the sub-systems making up a system and the framework for sub-system control and communication is architectural

THE TEACHING OF MATHEMATICS 2008, Vol. XI, 2, pp. 63 83 THE ROLE OF PROGRAMMING PARADIGMS IN THE FIRST PROGRAMMING COURSES Milena Vujošević-Janičić and Dušan Tošić Abstract. The choice of the first programming

1.1 McGraw-Hill The McGraw-Hill Companies, Inc., 2000 Objectives: To describe the evolution of programming languages from machine language to high-level languages. To understand how a program in a high-level

Quotes from Object-Oriented Software Construction Bertrand Meyer Prentice-Hall, 1988 Preface, p. xiv We study the object-oriented approach as a set of principles, methods and tools which can be instrumental

DEGREE PLAN INSTRUCTIONS FOR COMPUTER ENGINEERING Fall 2000 The instructions contained in this packet are to be used as a guide in preparing the Departmental Computer Science Degree Plan Form for the Bachelor's

Chapter 1 Object Oriented System Development with Objectives In this chapter, you will: Learn about OO development and Understand object-oriented concepts Recognize the benefits of OO development Preview

Data Abstraction and Hierarchy * This research was supported by the NEC Professorship of Software Science and Engineering. Barbara Liskov Affiliation: MIT Laboratory for Computer Science Cambridge, MA,

ABET General a. An ability to apply knowledge of computing and mathematics appropriate to the program s student outcomes and to the discipline b. An ability to analyze a problem, and identify and define

Engineering Process We need to understand the steps that take us from an idea to a product. What do we do? In what order do we do it? How do we know when we re finished each step? Production process Typical

www.capspace.org (01/17/2015) Software Engineering Transfer Degree This program of study is designed for associate-degree students intending to transfer into baccalaureate programs awarding software engineering

An Easier Way for Cross-Platform Data Acquisition Application Development For industrial automation and measurement system developers, software technology continues making rapid progress. Software engineers

What is a system? Software Engineering Software Processes A purposeful collection of inter-related components working together to achieve some common objective. A system may include software, mechanical,

Foundations for Systems Development ASSIGNMENT 1 Read this assignment introduction. Then, read Chapter 1, The Systems Development Environment, on pages 2 25 in your textbook. What Is Systems Analysis and