Programming Language Pragmatics, Fourth Edition
Format: PDF / Kindle (mobi) / ePub
Programming Language Pragmatics, Fourth Edition, is the most comprehensive programming language textbook available today. It is distinguished and acclaimed for its integrated treatment of language design and implementation, with an emphasis on the fundamental tradeoffs that continue to drive software development.
The book provides readers with a solid foundation in the syntax, semantics, and pragmatics of the full range of programming languages, from traditional languages like C to the latest in functional, scripting, and object-oriented programming. This fourth edition has been heavily revised throughout, with expanded coverage of type systems and functional programming, a unified treatment of polymorphism, highlights of the newest language standards, and examples featuring the ARM and x86 64-bit architectures.
- Updated coverage of the latest developments in programming language design, including C & C++11, Java 8, C# 5, Scala, Go, Swift, Python 3, and HTML 5
- Updated treatment of functional programming, with extensive coverage of OCaml
- New chapters devoted to type systems and composite types
- Unified and updated treatment of polymorphism in all its forms
- New examples featuring the ARM and x86 64-bit architectures
parser for the calculator language. Have it output a trace of its shifts and reductions. 2.36 Repeat the previous exercise using ANTLR. 2.37–2.38 In More Depth. 2.8 Bibliographic Notes Our coverage of scanning and parsing in this chapter has of necessity been brief. Considerably more detail can be found in texts on parsing theory [AU72] and compiler construction [App97, ASU86, CT04, FL88, GBJL01]. Many compilers of the early 1960s employed recursive descent parsers. Lewis and Stearns [LS68]
itself. It is also possible, though generally a sign of a program bug, for a name-to-object binding to have a lifetime longer than that of the object. This can happen, for example, if an object created via the C++ new operator is passed as a & parameter and then deallocated ( delete -ed) before the subroutine returns. A binding to an object that is no longer live is called a dangling reference. Dangling references will be discussed further in Sections 3.5 and 7.7.2. Object lifetimes generally
effect, without dynamic scoping. One option would be to have print integer use decimal notation in all cases, and create another routine, print integer with base , that takes a second argument. In a language like Ada or C++, one could make the base an optional (default) parameter of a single print integer routine, or use overloading to give the same name to both routines. (We will consider default parameters in Section 8.3.3; overloading is discussed in Section 3.6.2.) Unfortunately, using two
Names, Scopes, and Bindings 23. Why might it be useful to distinguish between the header and the body of a module? 24. What does it mean for a scope to be closed? 25. Explain the distinction between “modules as managers” and “modules as types.” 26. How do classes differ from modules? 27. Why does the use of dynamic scoping imply the need for run-time type checking? 28. Give an argument in favor of dynamic scoping. Describe how similar benefits can be achieved in a language without dynamic
Overloading of enumeration constants in Ada. print(month’(oct)); In Modula-3, and C#, every use of an enumeration constant must be prefixed with a type name, even when there is no chance of ambiguity: mo := month.dec; pb := print_base.oct; EXAMPLE 3.28 Overloading in Ada and C++ EXAMPLE 3.29 Overloading built-in operators In C, C++, and standard Pascal, one cannot overload enumeration constants at all; every constant visible in a given scope must be distinct. Both Ada and C++ have