Errata for Programming Languages - Principles and Practice, 2 nd Edition
by Kenneth C. Louden

First Printing (2002) and Second Printing (2003)

Last modified Tuesday, 16-Aug-2005 13:59:44 PDT

All errors listed below have been corrected in the third printing (July, 2005). If you have the first or second printing, you will need the errata list for the third printing, as well as the errors listed here. This list will now no longer change. To find out your printing number, look on the copyright page (the back of the title page). There is a list of numbers just below the phrase "Printed in the United States of America" on the lower left. The number on the far left is the number of the printing.

Changes since April 21, 2003

Since these errata are likely to get a significant number of additions over the next few months, I am listing links here to all changes made since the above date, in reverse chronological order:
4/20/05: Page 501
4/19/05: Page 403 (2nd error)
11/13/04:
Page 350
10/16/04: Page 380
5/17/04: Page 399 (3rd error)
4/28/04: Page 158, Page 170 (1st error)
3/19/04: Page 348 (Exercise 8.8)
3/18/04: Page 166
3/17/04: Page 363 (line 12)
2/14/04: Page 30
1/29/04: Page 416
12/18/03: Page 583
11/18/03: Page 170
10/3/03: Page 135, Page 146, Page 151
9/02/03: Page 399 (2nd error)
7/24/03: Page 531, Page 535, Page 537
7/22/03: Page 439
7/18/03: Page 398, Page 399, Page 400, Page 401, Page 402, Page 403, Page 404
7/17/03: Page 348 (Exercise 8.9)
5/27/03: Page 543, Page 637
5/12/03: Page 19 (3 errata), Page 489, Page 491
4/26/03: Page 359, Page 420 (2 errata)

Page 19

Figure 1.6, line 2: "not (V = 0)" should read "not(V = 0)".

Figure 1.6, line 4: "gcd (V, Y, X)" should read "gcd(V, Y, X)".

Line 3 below Figure 1.6: "a :- b, c, d" should read "a :- b, c, d.".

Page 30

Exercise 1.7, line 3: "{ if n <= 1) return 1;" should read "{ if (n <= 1) return 1;".

Page 52

Exercise 2.15(b), last line: "Exercises 2.12 and 2.13" should read "Exercises 2.13 and 2.14".

Page 86

Line 13: "A context-free language defines a lan-" should read "A context-free grammar defines a lan-".

Page 135

Figure 5.2: The brackets labeled main, q, and p should extend to the bottom of the figure. Thus, the figure should appear as follows:

Figure 5.2

Page 146

5th line from the bottom: "92" should read "98".

Page 151

Figure 5.17: An arrow to the smallest rectangle at the bottom right of the figure is missing. Thus, the figure should appear as follows:

Figure 5.17

Page 158

Third line from the bottom: "In the example of Figure 5.22..." should read "In the example of Figure 5.23...".

Page 166

Figure 5.26, line 5: "instantialtion" should read "instantiation".

Page 170

2nd paragraph, first line: "assigment" should read "assignment".

Last line: "... (the same as if one wrote *x = *y in C):" should read "... (the same as if one wrote x = y for pointer variables x and y in C):"

Page 211

Ada code in the lower middle of the page: The comment in the third-from-last line of code:
// note use of access attribute to get pointer to square
should read
-- note use of access attribute to get pointer to square

Page 247

11th line from bottom: "int gti (int x, int y)" should read "bool gti (int x, int y) "

Page 248

Line 2: "int larger_d = max(3.1,2.9);" should read "double larger_d = max(3.1,2.9);".

Page 250

Line 10: "integer i;" should read "i: integer; ".

Page 264

Figure 7.1, line 11: There is a missing closing parenthesis before the semicolon. Thus, "{ printf("%d\n",p(x,f());" should read "{ printf("%d\n",p(x,f()));".

Page 273

3rd line above Section 7.2.2: " if (p != 0 && p->>data == x)" should read " if (p != 0 && p->data == x)".

Page 299

Exercise 7.1, line 1: "prefix and postfix and draw the" should read "prefix and postfix form and draw the".

Page 322

1st Paragraph, line 4 of main code: " p(a[i]);" should read "inc(a[i]);".

Page 336

Figure 8.5: The return address field (after the access link field) is missing in each of the activation records. Thus, the figure should appear as follows:

Figure 8.5

Page 348

Exercise 8.8 (top of page), lines 9 and 10: "a[0] := 1;" and "a[1] := 1;" should read "a[0] = 1;" and "a[1] = 1;", respectively.

Exercise 8.9: The swap procedure is missing two semicolons; the correct code is:

void swap( int x, int y)
{ x = x + y;
y = x - y;
x = x - y;
}

Page 349

Exercise 8.15(a), line 3: "array[1..n] of integer " should read "integer arrays with the same number of elements".

Page 350

Exercise 8.16(b), last line: "void p( int x) { int x; ... }" should read "void q( int x) { int x; ... }".

Page 358

10th line from the bottom: "(function, imperative, object-oriented)" should read "(functional, imperative, object-oriented)".

Page 359

Section 9.1, line 9: "as polar coordinates (r,  )" should read "as polar coordinates (r,θ)".

Page 363

Line 11: The last word in the line (selectors) should be in bold face.

Line 12: The statement that the dequeue operation is a selector is incorrect. In fact, dequeue is a constructor, which, however, can be written in terms of the other constructors enqueue and createq, so it behaves as though it were a selector from the point of view of the axioms. (Such constructors are called non-primitive. A further discussion of this issue is beyond the scope of the text.)

Page 380

Figure 9.11, Line 34: "return q.next;" should read "return q;".

Page 383

Line 4: "Queue1.frontq q;" should read " - Queue1.frontq q;".

Page 398

4th and 5th lines from the end of Section 9.7: these lines should not be in code font, and should read:

frontq(enqueue(q,x)) = if emptyq(q) then x else frontq(q)
emptyq(enqueue(q,x)) = false

Page 399

Middle of page, 4th queue axiom: "if emptyq(q) then x else front(q)" should read "if emptyq(q) then x else frontq(q)".

Middle of page, last queue axiom: Last line should be indented to fall directly under the "if" in the preceding line.

Next to last line: "dequeue (dequeue (enqueue (createq, 3), 1))" should read "dequeue (dequeue (enqueue (createq, 3)))".

Page 400

Line 12: "if empty(q)" should read "if emptyq(q)".

Page 401

Lines 12, 14, 15, and 17: "front" should be replaced by "frontq" (one instance each on lines 12 and 17, two instances each on lines 14 and 15).

Page 402

Last line before Exercises: "or front(p) = front(q)" should read "or frontq(p) = frontq(q)".

Page 403

Exercise 9.4, line 1: "Figure 9.1" should read "Figure 9.2".

Exercise 9.14, line 5: "lookup: SymbolTable → name → value" should read "lookup: SymbolTable × name → value".

Page 404

Exercise 9.20, lines 3-5: These lines should read as follows:

(a)    frontq(enqueue(enqueue(createq,x), y)) = x
(b)    frontq(enqueue(dequeue(enqueue(createq,x)), y)) = y
(c)    frontq(dequeue(enqueue(enqueue(createq,x), y))) = y

Page 405

Exercise 9.22, line 4: "follows:" should read "follows (in Ada syntax):".

Exercise 9.24, line 7: "maxsize: → integer" should read "maxsize: integer".

Exercise 9.27: This exercise should be replaced by the following: "Compare the handling of infix operators defined in C++ namespaces to Ada's handling of infix oeprators defined in packages. Are there any significant differences?"

Page 407

Exercise 9.34, line 4: "create: → Item" should read "create: Item".

Page 416

Line 11 (below Fig. 10.2): "statements, z.re == 1.0, z.im == 1.0, ..." should read "statements, z.re == 1.0, z.im == 2.0, ...".

Page 420

10th line from the bottom: " q = d;" should read "d = q;".

5th line from the bottom: "q = (Deque) d;" should read "d = (Deque) q;".

Page 422

Lines 5-7: The code

public boolean equals ( Complex c)
{ return re == c.realpart()
&& im == c.imaginary part(); }

should be replaced by the following code

// Must keep Object class definition for overriding:
public boolean equals ( Object obj)
{ Complex c = (Complex) obj;
return re == c.realpart()
&& im == c.imaginarypart(); }

Page 425

The figure at the bottom of the page should appear as:

Figure, p. 425

Page 427

Line 3: "class LinkableComplex extends Complex, LinkableObject " should read "public class LinkableComplex extends Complex, LinkableObject ".

Page 430

Middle of page: "interface LinkableObject " should read "public interface LinkableObject ".

6th line from bottom: "class LinkableComplex" should read "public class LinkableComplex".

Page 432

Line 1: "class BorderedRectangle extends Rectangle " should read "public class BorderedRectangle extends Rectangle".

Lines 8-10:  These lines should be replaced by the following code:
public double area()
/* assumes Rectangle has accessor methods
getWidth and getHeight */
{ return (getWidth()+2*border) * (getHeight()+2*border);
}

Page 437

Figure 10.11, line 5: "int empty()" should read "bool empty()".

Page 438

Line 14: "LinkableObject* x = new linkableObject; " should read "LinkableObject* x = new LinkableObject;".

Page 439

Figure 10.12, line 5 (bottom of page): "int empty()" should read "bool empty()".

Page 440

Figure 10.12, line 10: "{ return rear->next->data; " should read "{ return rear->next->data; }".

Page 450

Figure 10.17, line 17: "temp < front. " should read "temp <- self front.".

Page 451

Figure 10.18, 2nd and 3 rd lines from the bottom: these lines should read as follows:
 (Complex new setReal: ((self realPart) + (y realPart)))
                setImag: ((self imagPart) + (y imagPart))

Page 483

Figure 11.6, line 3: "(a == b) && (a! = 0)" should read "(a == b) && (a != 0) ".

Page 489

Line 2: There is a right parenthesis missing at the end of the line: "(car (cdr (cdr L))" should read " (car (cdr (cdr L)))".

Page 490

3rd paragraph, line 7: "The language defines tail recursion as equivalent to a loop in an imperative language." should read "The language specification requires that tail recursion be implemented as a loop, as in an imperative language."

Page 491

Section 11.3.4, line 8: "(define (sqr x) (* x x)) " should read "(define (square x) (* x x))".

Page 501

Line 16 (middle of page): "datatype 'a myoption" should read "datatype 'a option".

Page 519

Figure 11.10: The function trunc listed in parentheses under RealFrac should be truncate .

Page 520

Line 15: "instance Show (BST a) where show = ... " should read "instance Show a => Show (BST a) where show = ... ".

Page 531

Exercise 11.8(g), last line : "1 ≤ x < yzn" should read "1 ≤ xyzn".

Page 532

Exercise 11.16, 2nd to last line : "(2 . (3 (4 . ())))" should read "(2 . (3 . (4 . ())))".

Page 535

Exercise 11.40: The code for delayed-map (lines 3-6) and L (lines 11-12) is incorrect. The correct code is as follows:
(define (delayed-map f L)
(if (null? L) '()
(delay (cons (f (car (force L)))
(delayed-map f (cdr (force L)))))))

(define L
(delayed-map show (delay (intlist 1 100))))

Page 537

Notes and References, 3rd paragraph, line 4: "Turner [1992]" should read "Turner [1982]".

Page 543

Example 3, 3rd paragraph from the bottom: the second line in the list of four statements ("arms(horse,0)") should be deleted (it is an axiom).

Page 563

Figure 12.6, 2nd from last line: "remove (P,[I|Is],Nis) :-" should read "remove(P,[I|Is],Nis) :-".

Page 567

Figure 12.8, line 5: "append(L1,[H|R1],S), " should read "append(L1,[H|R1],S).".

Page 583

Last line: "{n = 5, i = 0,fact = 120}" should read "{n = −5, i = 0,fact = 120}".

Page 594

Middle of the page: "reduce_all(E,V) :- integer(V), !." should read "reduce_all(V,V) :- integer(V), !. ".

Two lines below previous correction: "Now if we want the final semantic value of an expression E, we must write reduce_all(E)." should read "Now if we want the final semantic value V of an expression E, we must write reduce_all(E,V) ."

Page 634

Figure 14.5: The following code should be inserted after line 3:
main()
{ int myid;
  /* code to input a,b goes here */
  for (myid = 0; myid < NUMPROCS; ++myid)
    if (fork() == 0)
    { multiply(myid);
exit(0);
}
for (myid = 0; myid < NUMPROCS; ++myid)
    wait(0);
/* code to output c goes here */
return 0;
}

Page 637

9th line from the bottom: "Queue myqueue = new Queue(...);" should read "Queue q = new Queue(...); ".

Page 658

2rd paragraph, line 4: "such as signal or delay" should read "such as signal or wait".

Page 659

Figure 14.11, line 3: "entry delay; " should read "entry wait; -- use instead of delay, which is reserved in Ada".