Main Page

From TDPL Errata
Jump to: navigation, search

Errata for "The D Programming Language" book

The list below is created by readers and D users like you and maintained by the book's author.

All code samples can be downloaded off here (also refer to the related announcement). Get individual examples or all.zip to get them all. The examples that currently don't work as expected with the reference implementation are in the "shouldwork" subdirectory.

To add entries, please email Andrei. Editing of this page has been disabled due to spamming. Don't forget to specify the printing, which can be seen at the bottom of the copyright page (the one just before Contents) and reads like "First printing, May 2010".

Page Print Current text Correction Submitter
xxv 1 justfy justify Björn Fahller
5 1 %i for integers %d for integers Andrei Alexandrescu (on behalf of Roel)
6 1 the code sample above also introduced the if statement there is no if statement above Benjamin Shropshire
8 1 the large example should use size_t instead of uint Andrei Alexandrescu (on behalf of bearophile)
8 1 The use of dictionary[word] in the dictionary code sample does not compile with dmd 2.050+. Instead, the code should use dictionary[word.idup] or dictionary[to!string(word)] to convert word of type char[] to type string, which is required by the dictionary. Andrei Alexandrescu (on behalf of Caligo)
12 1 Speaking of state, let's write a recursive implementation of binarySearch that doesn't reassign index at all: Replace "index" with "input" Geert Fannes
12 1 if ( mid > value ) return binarySearch( input[0 .. i] );

if ( mid < value ) return binarySearch( input[i + 1 .. $] );

if ( mid > value ) return binarySearch( input[0 .. i], value );

if ( mid < value ) return binarySearch( input[i + 1..$], value );

Byron Heads
12 1 the compiler modifies the argument the compiler modifies the arguments Andrei Alexandrescu
8 1 foreach(word; split(strip(line))) Should be foreach(word; splitter(strip(line))) for consistency with the example on page 8 and for better efficiency. Michal Mocny
13 1 Doesn't mention the need to import std.algorithm to gain access to the sort function. 'Add `, std.algorithm` to the first line.' Bernard Helyer
17 1 better makes a copy of it better make a copy of it Philip Zigoris
18 1 Text mentions std.algorithm find, but code uses haystack.find(needle). At this point the reader has not been explained that both forms work. Michal Mocny
22 1 stats example will not compile and run as is readf should be stdin.readf, and need to add a try/catch for std.conv.ConvError. Dan Renfro
22 1 Object.factory.Object four lines from the bottom of the page. There is confusion between the use of "." in code and typographically. Michal Mocny
22 1 The bottom of page 22 and the top of page 23 refer to Max, which hasn't been yet defined. For clarity the references should be changed to Min. Thanate Dhirasakdanon
23 1 aside from a slight change in accumulate, everything is exactly the same The member needs to be initialized to -double.max (and possibly renamed) Eitan Frachtenberg
26 1 In D, slicing could never occur. This should probably be: In D, C++'s damaging slicing could never occur. Andrej Mitrovic
31 1 List of keywords Keywords immutable, lazy, pure, nothrow, and shared are missing (more detail) Jonathan M Davis
36 1 The ASCII values for backspace, formfeed, line feed and carriage return seem to be given in octal. Jos
39 1 you can suffix a string literal with c, w or d, which, similar to the homonym character literal suffixes, force the type. you can suffix a string literal with c, w or d, which, force the type. char literals make no reference to suffixes Benjamin Shropshire
44 1 Figure 2.3: Implicit integral conversions. The figure shows both integrals and floating-point types. Geert Fannes
49 1 Bullet 4 mentions "A kind is one of the following keywords: ..." and is missing "return" while it does appear in table 2.4. Also, the order of keywords mentioned and table listing is not the same (is there any ordering/grouping?). Michal Mocny
49 1 "A kind is one of..." "A kind can be one of..." There also seem to be a few mismatches with the online documentation, e.g. the inout keyword. Andreas Guðmundsson
50 1 "evaluating postincrement or postdecrement increments" "evaluating postincrement or postdecrement modifies" Eli Sternheim
50 1 If the indexing expression is on the left-hand side of an assignment operation (e.g., arr[i] = e) and a is an associative array arr is an associative array, not "a" Andrej Mitrovic
50 1 Section 2.3.5.4. The text implies that "arr[i] is the ith (zero-based) element of... associative array arr", which is incorrect. Rephrase Michal Mocny
53 1 (see the definition of nonzero 46) "on page" should be inserted Geert Fannes
56 1 Section 2.3.11 In the first code block table["hello"] = 0; should be = 1; Michal Mocny
57 1 a is c && writefln("Indeed... not the same"); a is c && writeln("Indeed... not the same"); Andrej Mitrovic
60 1 1. If a and b have the same type, ... 2. else if a and b are integrals, ... 6. else try implicitly converting a to b's type and b to a's type; 1. If b and c have the same type, ... 2. else if b and c are integrals, ... 6. else try implicitly converting b to c's type and c to b's type; Cassio Neri
67 1 a colon present by itself is not a statement a semicolon present by itself is not a statement Andrew C Edwards
68 1 2nd example on page Text says "If you instead want to bind the else to the first if..." but the braces in the example that follows bind it to the second if. Jonathan M Davis
68 1 The enum syntax is used without having been introduced. Michal Mocny
68 1 In the second code block, the last angle bracket is misplaced and should come before the else. Geert Fannes
70 1 ...for example, we could define numeric globally ... ...for example, we could define Numeric globally ... Karim Naqvi
75 1 Chapter 12 will deal with the latter case, Chapter 12 will deal with the last case, Andrew Talbot
76 1 ref counts on and exact match of representation ref counts on an exact match of representation Jonathan M Davis
76 1 ...ref counts on and exact match... Replace "and" with "an" Geert Fannes
81 1 Should explain what happens with locals hidden by the "with" statement. Michal Mocny
82 1 All controlled statements must be block statements; that is, they must be enclosed by braces. The statement is incorrect and should be removed. C++ has that restriction. D does not. (more detail) Jonathan M Davis
82 1 The first type <Ek> that is <Ex> or a class derived from it The first type <Ek> that is <Ex> or a superclass of it Simen Kjaeraas
87 1 The lowering of scope(failure) is almost identical to that of scope(exit) The lowering of scope(failure) is almost identical to that of scope(success) Eitan Frachtenberg
89 1 Bibentry [12] links to D 1.0 assembler. Michal Mocny
94 1 After the code block foreach ( ref ... ), you write "The ref informs the compiler that we want to reflect assignment...". I think the word "reflect" is a poor work choice, since, although grammatically correct, one could easily deduce that ref stands for "reflect", and don't think that is correct. Michal Mocny
103 1 so write "no palindrome" and bail out. so write "not palindrome" and bail out. Andrew C Edwards
103 1 Only if all tests succeed and args got shorter than two elements (the program considers arrays of zero or one element palindromes), the program prints "palindrome" and exits. Only if all tests succeed and args get shorter than two elements (the program considers arrays of zero or one element palindromes), [will/does] the program print "palindrome" and exit. Andrew C Edwards
106 1 auto array = new int[10] ;

array. length += 1000; // Grow
assert(array. length == 1010);
array. length /= 10;
assert(array. length == 101); // Shrink

auto array = new int[10] ;

array. length += 1000; // Grow
assert(array. length == 1010);
array. length /= 10; // Shrink
assert(array. length == 101);

Roberto C. B. Ballona
114 1 Second paragraph: "[associative arrays]... possible to map a value of a different type..." I would change that to "of another type" since types need not necessarily be different. Michal Mocny
114 1 Section 4.4.1 first paragraph, last sentence "The type of aa.length is size_t" -- this statement was just said in the first sentence. Michal Mocny
116 1 last line of example 1: assert(a2["Sam"] == 3.5; // versa should read: assert(a1["Sam"] == 3.5; // versa Andrew C Edwards
117 1 it is preferable to iterate with foreach instead of fetching keys of values it is preferable to iterate with foreach instead of fetching keys or values Alix Pexton
124 1 [H][a][l][l][å][,][ ][V][ä][r][d][!] [H][a][l][l][å][,][ ][V][ä][r][l][d][!] (värd means worth, not world) Simen Kjaeraas
124 1 As such, the pointer does not have information on whether the chunk starts and ends. Please rephrase. Geert Fannes
125 1 "of an array with a.ptr" "of an array arr with arr.ptr" Eli Sternheim
129 1 Table 4.5 does not include a.byKey() and a.byValue(). Alix Pexton
144 1 Three equally specialized functions: either could be called Three equally specialized functions: each could be called Andrew Talbot
146 1 The transmogrify(uint) overload in calvin.d is ... The transmogrify(uint) overload in hobbes.d is ... Cassio Neri
148 1 First code snipped is missing an import import hobbes; Andrej Mitrovic
148 1 Second code snippet: missing alias to susie. The code must alias all modules with overloads. alias susie.transmogrify transmogrify; Andrej Mitrovic
161 1 to!string(arg0), to!string(arg1), to!string(arg2), to!string(arg3) to!string(a0), to!string(a1), to!string(a2), to!string(a3) Andrew C Edwards
162 1 forwards four, not two, arguments to write forwards four, not three, arguments to write

(?)

Roberto C. B. Ballona
163 1 Last paragraph before 5.10.2.2 Please insert explanation on why tuples do not have literals. Geert Fannes
174 1 regular variables for m, a and b. regular variables for m, a and c. Andrew Talbot
179 1 The third box from the top seems like an internal unit test for the example above it (use of __traits(compiles, …)). David Nadlinger
181 1 assert(t.a == 0.4 && isnan(t.b)); assert(t.a == 0.4 && isNaN(t.b)); Andrew Talbot
185 1 The code below efficiently initializes a fixed size array with 0.0, 0.1, 0.2,..., 1.28: The code below efficiently initializes a fixed size array with 0.0, 0.1, 0.2,..., 12.7: Alix Pexton
188 1 Last line in the first example: assert(b1.data is null); assert(b1.data !is null); Andrej Mitrovic
189 1 initialization orderHere's how the ordering works. Here's how the ordering works. (can't see where the extra words originated) Alix Pexton
189 1 MA imports MB. Then A's static class constructors run before B's.

MB imports MA. Then B's static class constructors run before A's.

MA imports MB. Then B's static class constructors run before A's.

MB imports MA. Then A's static class constructors run before B's.

Andrej Mitrovic
191 1 auto color = c.bgColor();   // call a contact method auto color = c.bgColor();   // call a friend method Andrej Mitrovic
191 1 (in this case, currentBgColor) currentReminder is also a state variable introduced by Friend. Geert Fannes
196 1 being scope inside a class being scope inside a class Andrew Talbot
199 1 class PostUltimateWidget : Widget { ... } class PostUltimateWidget : UltimateWidget { ... } Alix Pexton
208 1 Last line of example 2: return text == that.text; return text == that2.text; Andrej Mitrovic
215 1 Last line of example 2: override void doUntransmogrify() { ... } This method does not override any interface methods, change to: void doUntransmogrify() { ... } Andrej Mitrovic
216 1 enforce() is undefined Missing import std.exception; Andrej Mitrovic
217 1 Example 2 BrokenInTwoWays should implement Transmogrifier. Simen Kjaeraas
219 1 class Rectangle : RectangularShape The Rectangle class has already been defined as the Base class for all the derived classes in the example. A different name should be used for the class that implements RectangularShape. Andrej Mitrovic
228 1 Then we define Sprite3 to implement ObservantActor and VisualActor: Then we define Sprite3 to implement HyperObservantActor and VisualActor: Alix Pexton
234 1 The discussion of Parameterized Classes and Interfaces doesn't mention anywhere the need to import std.array to gain access to the empty, back, and popBack functions as used in StackImpl. Add std.array; to the first line. Andrew C Edwards
235 1 Java and C# use heterogeneous translation for their parametrized types. As far as I know Java uses homogeneous translation. The Integer in LinkedList<Integer> is erased, and LinkedList<int> doesn't even compile. Enrico Kravina
248 1 …, again this(this) is invoked for the field w of field w2. …, again this(this) is invoked for the field w1 of field w2. David Nadlinger
248 1 // this(this) called for b.w // this(this) called for b.w1 Andrej Mitrovic
249 1 // this(this) for d.w2.w // this(this) for d.w2.w1 Andrej Mitrovic
267 1 Figure 7.2 Hatched area is barely visible. Geert Fannes
267 1 "hashed areas", "hashed bytes" "hatched areas", "hatched bytes" Andrew Talbot
270 1 specify the desired initializer in brackets specify the desired initializer in braces Andrew Talbot
271 1 many uses of union actually use sounds awkward, rephrase Andrew Talbot
271 1 manipulation manipulations Andrew Talbot
272 1 Tag._void Tag._tvoid Jonathan Amsterdam
273 1 void f(ref double x) void fun(ref double x) Andrej Mitrovic
279 1 struct /* or class */ Select2(bool cond, T1, T2) { // Or class struct Select2(bool cond, T1, T2) { // Or class Alix Pexton
288 1 immutable expresses absolute, context-dependent immutability. immutable expresses absolute, context-independent immutability. Jonathan M Davis
288 1 immutable expresses absolute, context-dependent immutability replace "dependent" with "independent" Geert Fannes
289 1 missing closing parenthesis: static assert(is(typeof(origin.x) == immutable(int)); static assert(is(typeof(origin.x) == immutable(int))); Andrej Mitrovic
290 1 ds[1] = 4.5; // ? ds.payload[1] = 4.5; // ? Andrej Mitrovic
307 1 § 9.4 discussed nothrow functions § 5.11.2 discussed nothrow functions Alix Pexton
309 1 catch Exception e, while e = e.next != null catch Throwable e, while e = e.next !is null Andrej Mitrovic
309 1 code: import std.contracts, throw new CustomException("fun", x); import std.exception, throw new CustomException("x is less than 0: ", "fun", x); Andrej Mitrovic
318 1 throw new CustomException("fun", x); throw new CustomException("Negative value ", "fun", x); Michal Mocny
325 1 D defines such a function in module std.contracts D defines such a function in module std.exception Andrej Mitrovic
326 1 import std.contracts; import std.exception; Andrej Mitrovic
327 1 ..standard library function std.contracts.enforce(false), import std.contracts ..standard library function std.exception.enforce(false), import std.exception Andrej Mitrovic
330 1 // Require str // Require spec Jonathan Amsterdam
335 1 void push (T value) in { assert(!empty); } void push (T value) Alix Pexton
336 1 final void push (T value) { enforce(!empty); pushImpl(value); enforce(value == topImpl()); } final void push (T value) { pushImpl(value); enforce(value == topImpl()); } Alix Pexton
338 1 In the enumeration of the items that a module may start with, comments are missing. A module may start with a comment which has '/' as its first character (that character, being ASCII, doesn't affect adversely the autodetection process). Vladimir Panteleev
340 1 importThe order of importing modules is irrelevant. The order of importing modules is irrelevant. Alix Pexton
357 1 else if (info.dwMajorVerson == 6 && info.dwMinorVersion == 0) { winVersion = WinVersion.preVista; } else { winVersion = WinVersion.preVista; else if (info.dwMajorVerson == 6 && info.dwMinorVersion == 0) { winVersion = WinVersion.vista; } else { winVersion = WinVersion.postVista; Alix Pexton
357 1 The initialization of OSVERSIONINFOEX with a constant is confusing. Michal Mocny
356 1 "entire applications may be written entirely in SafeD." "entire applications may be written in SafeD." Eli Sternheim
360 1 Using PreFinalRelease is correct, but it would be nice to replace it with FinalRelease to integrate with the previous example. Andrew Talbot
361 1 Attempting to set a version in both the command line and a source file is, again, in error. Attempting to set a version in both the command line and a source file is, again, an error. Alix Pexton
361 1 No mention of the global debug flag. Andrei Alexandrescu (on behalf of JRM)
361 1 The debug was defined The debug declaration was defined Jonathan Amsterdam
362 1 std.contracts in the standard modules summary table This should be replaced with std.exception Andrej Mitrovic
368 1 Missing semicolons in two opUnary methods return CheckedInt(mixin(op ~ "value;")); mixin(op ~ "value;"); Andrej Mitrovic
372 1 Broken return statements in opBinary "Addition", "Subtraction" and "Multiplication" All three should be fixed with: return CheckedInt(result); Andrej Mitrovic
379 1 The method names substitute "slice" for "array" throughout Replace "array" with "index" Geert Fannes
382 1 inorder traversal of the tree preorder traversal of the tree Eric Lawless
383 1 // Calls object.opApply(k, v) Comment is mistaken because opApply passes a delegate, too. Michal Mocny
384 1 static if (op == "+") { return opSubtract(rhs); } static if (op == "-") { return opSubtract(rhs); } Eric Lawless
386 1 a.opDispatch!"do_something_cool"(5, 6) has a trailing quote that needs to be removed. By the way, opDispatch is ridiculously cool. Michal Mocny
393 1 Also, the speed gap between processing elements and memory is also increasing. "also" occurs twice Eli Sternheim
401 1 Main thread: 999 \ Secondary thread: 999 Main thread: 99 \ Secondary thread: 99 Andrew Talbot
401 1 The example starting at the bottom of page 401 needs to import std.exception. Also, on dmd 2.051 the example throws an exception at runtime "std.concurrency.MessageMismatch: Unexpected message type" after printing all messages. Martin Waite
406 1 The example doesn't need std.algorithm. Andrew Talbot
406 1 foreach (immutable(ubyte)[] buffer; stdin.byChunk(bufferSize)) send(tid, buffer); foreach (buffer; stdin.byChunk(bufferSize)) send(tid, buffer.idup) Andrew Talbot
407 1 tgt.write(buffer); stdout.write(buffer); Andrew Talbot
413 1 Anyway, real is meant mostly for high-precision temporary results and not for data interchange, so it makes little sense to want to share it anyway. "Anyway" occurs twice Eli Sternheim
418 1 For consistency with the example on page 415, balance() should be a property in the example at the bottom of this page, too. Andrew Talbot
419 1 no address of a field can escape a synchronized address. no address of a field can escape a synchronized (class/object/method/...). Alix Pexton
419 1 There are shared classes and shared structs, and then synchronized classes. Could there be synchronized structs? Michal Mocny
422 1 setMutex setSameMutex Jonathan Amsterdam
413 1 Last six lines of code have wrong tab sizes. 2 spaces instead of 3 Eli Sternheim
Personal tools