Programming language concepts — Third edition Carlo Ghezzi, Politecnico di Milano Mehdi Jazayeri, Technische Universität Wien John Wiley & Sons New York Chichester Brisbane Toronto Singapore 2 Chap. Copyright 1996 by Carlo Ghezzi and Mehdi Jazayeri. All rights reserved. ISBN 0-000-000000-0 ABCDEFGHIJ-DO-89 3 T A B L E O F C O N T E N T S TABLE OF CONTENTS 3 Introduction 15 Software development process 16 Languages and software development environments 17 Languages and software design methods 19 Languages and computer architecture 21 Programming language qualities 25 Languages and reliability 26 Languages and maintainability 27 Languages and efficiency 28 A brief historical perspective 29 Early high-level languages: FORTRAN, ALGOL 60, and COBOL 33 Early schisms: LISP, APL, and SNOBOL4 33 Putting them all together: PL/I 35 The next leap forward: ALGOL 68, SIMULA 67, Pascal, and BASIC 35 C and the experiments in the 70’s 36 The 80’s: ML, Ada, C++ and object orientation 37 The present 38 A bird’s eye view of programming language concepts 39 A simple program 39 Syntax and semantics 41 Semantic elements 42 Program organization 44 Program data and algorithms 46 External environment 47 Bibliographic notes 48 Exercises 48 Syntax and semantics 51 Language definition 52 Syntax 52 Abstract syntax, concrete syntax and pragmatics 56 Semantics 57 Language processing 64 Interpretation 64 Translation 66 The concept of binding 68 4 Variables 69 Name and scope 70 Type 72 l_value 76 r_value 77 References and unnamed variables 79 Routines 80 Generic routines 86 More on scopes: aliasing and overloading 87 An abstract semantic processor 89 Execution-time structure 92 C1: A language with only simple statements 93 C2: Adding simple routines 94 C3: Supporting recursive functions 99 C4: Supporting block structure 104 Nesting via compound statements 105 Nesting via locally declared routines 108 C5: Towards more dynamic behaviors 113 Activation records whose size becomes known at unit activation 113 Fully dynamic data allocation 114 Parameter passing 120 Data parameters 120 Routine parameters 125 Bibliographic notes 129 Exercises 130 Structuring the data 135 Built-in types and primitive types 136 Data aggregates and type constructors 138 Cartesian product 139 Finite mapping 140 Union and discriminated union 144 Powerset 146 Sequencing 147 Recursion 147 Insecurities of pointers 148 Compound values 151 User-defined types and abstract data types 152 Abstract data types in C++ 153 5 Abstract data types in Eiffel 155 Type systems 159 Static versus dynamic program checking 160 Strong typing and type checking 161 Type compatibility 162 Type conversions 165 Types and subtypes 167 Generic types 169 Summing up: monomorphic versus polymorphic type systems 170 The type structure of existing languages 173 Pascal 173 C++ 175 Ada 177 Implementation models 184 Built-in and enumerations 184 Structured types 186 Cartesian product 187 Finite mapping 188 Union and discriminated union 189 Powersets 191 Sequences 192 Classes 192 Pointers and garbage collection 193 Bibliographic notes 195 Exercises 196 Structuring the computation 199 Expressions and statements 200 Conditional execution and iteration 205 Routines 212 Style issues: side effects and aliasing 214 Exceptions 220 Exception handling in Ada 222 Exception handling in C++ 225 Exception handling in Eiffel 228 Exception handling in ML 233 A comparative evaluation 234 Pattern matching 237 Nondeterminism and backtracking 240 6 Event-driven computations 242 Concurrent computations 244 Processes 249 Synchronization and communication 251 Semaphores 251 Monitors and signals 254 Rendezvous 257 Summing up 260 Implementation models 262 Semaphores 265 Monitors and signals 266 Rendezvous 267 Bibliographic note 268 Exercises 269 Structuring the program 273 Software design methods 275 Concepts in support of modularity 276 Encapsulation 277 Interface and implementation 279 Separate and independent compilation 281 Libraries of modules 282 Language features for programming in the large 283 Pascal 284 C 287 C++ 290 Encapsulation in C++ 291 Program organization 291 Grouping of units 293 Ada 296 Encapsulation in Ada 296 Program organization 297 Interface and implementation 299 Grouping of units 301 ML 303 Encapsulation in ML 303 Interface and implementation 305 Abstract data types, classes, and modules 306 Generic units 307 7 Generic data structures 307 Generic algorithms 308 Generic modules 310 Higher levels of genericity 311 Summary 313 Bibliographic notes 313 Exercises 314 Object-oriented languages 317 Concepts of object-oriented programming 319 Classes of objects 320 Inheritance 321 Polymorphism 322 Dynamic binding of calls to member functions 323 Inheritance and the type system 325 Subclasses versus subtypes 325 Strong typing and polymorphism 326 Type extension 327 Overriding of member functions 327 Inheritance hierarchies 331 Single and multiple inheritance 331 Implementation and interface inheritance 332 Object-oriented programming support in programming languages 333 C++ 333 Classes 334 Virtual functions and dynamic binding 335 Use of virtual functions for specification 336 Protected members 337 Overloading, polymorphism, and genericity 339 Ada 95 339 Tagged types 339 Dynamic dispatch through classwide programming 342 Abstract types and routines 342 Eiffel 343 Classes and object creation 343 Inheritance and redefinition 343 Smalltalk 345 Object-oriented analysis and design 345 Summary 346 8 Bibliographic notes 347 EXERCISES 348 Functional programming languages 353 Characteristics of imperative languages 354 Mathematical and programming functions 355 Principles of functional programming 356 Values, bindings, and functions 357 Lambda calculus: a model of computation by functions 358 Representative functional languages 362 ML 362 Bindings, values, and types 363 Functions in ML 363 List structure and operations 365 Type system 366 Type inference 369 Modules 371 LISP 373 Data objects 373 Functions 374 Functional forms 376 LISP semantics 377 APL 377 Objects 377 Functions 378 Functional Forms 379 An APL Program 380 Functional programming in C++ 382 Functions as objects 382 Functional forms 383 Type inference 385 Summary 386 Bibliographic notes 386 Exercises 387 Logic and rule-based languages 389 The"what" versus "how" dilemma: specification versus implementation 389 A first example 391 Another example 393 9 Principles of logic programming 395 Preliminaries: facts, rules, queries, and deductions 395 An abstract interpretation algorithm 400 PROLOG 407 Functional programming versus logic programming 411 Rule-based languages 413 Bibliographic notes 416 Exercises 416 Languages in context 419 Languages and their execution context 420 User interfaces 420 Interface with databases 421 Languages and the context of the application area 421 Embedded applications 421 Languages and the context of the software development 421 Conclusions 422 10 Chap.