Errors and imperfections found in Harper's book

Errors and imperfections found so far in Harper's book

I will try to keep this up to date. Please report further errors or imperfections to me.

The errors listed below vary a lot in their degree of significance -- some are simple typos while others are more serious.

Page numbers refer to this copy of the version for printing; the version for reading online has different pagination. Line -n means n lines from the bottom of the page.

Acknowledgements: Ewen Denney, Ben Kavanagh, Andy Koppe, Kenneth MacKenzie, Jan Obdrzalek.

Note: There is a slightly improved version with a later date on the author's website, but hardly any of these errors have been repaired and some other errors have been introduced.


Comments are not explained anywhere! One of the first examples on p7 uses comments, but the (* and *) symbols are never explained. The sample program in chapter 1 fills four pages without a single comment.

It might be helpful to say something somewhere about the use of the final semicolon in an interactive session to tell ML to start work.

p10, line -10, grammar for rexp: This should read

   rexp ::= rtrm | rtrm + rexp

p24, line -5, fixed point number: He means a number without any digits to the right of the decimal point. "Fixed point" normally includes numbers with a fixed number of digits to the right of the decimal point.

p25, 2 lines before 2.2.1, chapter 13: Should be chapter 12.

p28, line 6, 2 downarrow 2: Should be 7 downarrow 7.

p34, last line, and p35, line 4: If this is supposed to refer to e as in mathematics, 2.17 should be changed to 2.72 (or 2.71828182846).

p37, first 3 lines: We already get non-discarded shadowed bindings in section 3.4, with let/local.

p42, display in middle of page: one R is in the wrong font.

p44, example at bottom of page, step 4: this is written as though x was bound to 2.0 in step 3 instead of to 4.0. The result of step 4 should be 1.414 instead of 1.189.

p52, rules for pattern formation: what about

   val (x,y):int*int = (2,3)
   val (_:int,y:int) = (2,3)
Should say somewhere here that variable repetition isn't allowed, and that there are more kinds of patterns to come later.

p57, dist, dist', dist2: sqrt should be Math.sqrt, 4 times. Also, dist and dist' do not give the distance between x and y but rather the distance of the point (x,y) from the origin in R^2. The Euclidean distance function on R^2 is given by

   fun edist ((x:real, y:real), (x':real, y':real)): real =
       Math.sqrt ( (x-x')*(x-x') + (y-y')*(y-y') )
In the definition of dist2, abs(x-y) is given as an alternative definition of the distance between two points. This is a correct definition of distance in R^1; the other version is again an incorrect definition of distance in R^2.

p57, 3 lines after dist is first defined: the result is approximately 3.606, not 4.0.

p58, line 1, labeled: should be label

p58: doesn't explicitly say that tuples are a special case of records, which would make this look less ad hoc.

p58, near bottom, #lab: this halfway suggests that you have to define it yourself, which is not the case.

p61, sentence after recip: this belongs in section 4.2 where fun is introduced.

p68, computation of factorial 3 on the bottom half of page: This would be clearer if parentheses were added as in the version above, e.g. 3*(2*(1*1)).

p72, end of first paragraph, "fib of": should be "of fib".

p75, line 3,every variable in a pattern has a type associated with it: Not true, see e.g. p55-56. (This doesn't invalidate the point that is being made here; types could have been included everywhere.)

p76, lines 2-3, most general (least restrictive): This doesn't really make sense until polymorphism is introduced, and there is no link to that or from that, except repetition of the same point in the middle of p76.

p82, line before second "double" example, (with a warning): not in Moscow ML

Same line, the following one will be rejected: not by Moscow ML [Don't know if this is an error in Moscow ML or in the book -- does the definition of ML specify the behaviour he describes?]

p82, line -3, is arises: arises

p87, middle: It should say somewhere here, and maybe again in the next chapter, that value constructors can appear in patterns.

p88, top, non-associativity of :: : Too cryptic.

p93, expt function, "then" part of if-then-else: SOME b*b should be SOME(b*b).

p94, first line: remove "(" or add ")".

p94, penultimate paragraph: The remark about predecessors may be confusing rather than helpful.

p94, last line: max should be Int.max.

p103, line 2: occurrence

p104, map' (and map later): These would be better in section 11.4

p112, title of section 12.1.1, Primitve: Primitive

p115, example: toString should be Int.toString.

p116, example: ditto

p119, lines 9-10, a value carrying constructor ... has type string -> exn: This is true for value-carrying constructors as they have been introduced here, but ML allows exceptions to carry values of types other than string. Full stop missing before "Thus".

p122, line 5, typ: wrong font. Bad line break 4 lines later.

p122, examples in second half of page: t is unbound; after execution, y is bound to 3 and z is bound to 8.

p123, last sentence before 13.2: () is assured provided evaluation terminates and does not raise an exception.

p123, line -2, the second implementation of rot3 above: this refers to p127, which is not above but below.

p127, under the first rot3 example: a, b, and c are x, y, and x.

p131, middle of page, stl: I don't think patterns with "as" have been explained.

p132-133, first paragraph of 13.6: Array.array, Array.sub, Array.update. Array.length instead of size.

p133, line 3, V; same for p135, lines 1 and 4: presumably refers to one of the appendices in part V of the book.

p133, line 8, multiplication's: multiplications

p134, first paragraph: font of C and C'

chapter 14: This describes components of the TextIO library structure and most of the types and values need to be written TextIO.x instead of just x. An exception is print.

p136, lines 6-7: bad line break

p136, end of the second complete paragraph, raises the exception TextIO.IO: the exception is IO.Io [According to the SML Basis Library documentation -- the Moscow ML library says Io.Io, which doesn't exist, and implements IO.Io.]

p136, last line: option is in the wrong font

p137, line 8, transitive: transient

p137, line -2, Posix: should be POSIX.

p140, item 3: value constructors

p140, line -8, (Recent versions of) ML have lazy data types: One recent version. These are not part of the Standard ML language. (This point is mentioned at the end of the section.)

p141, line 3, every: ever

p141, line 7: of an on-line

p155-156, section 18.1.1: An additional form of specification that is not mentioned is eqtype, which is just like type except that it specifies a type that admits equality. [Yet another form is datatype replication. The existence of this might be mentioned but it doesn't need to be explained.]

p156, lines 2-3: bad line break.

p160, line 3, sides: side

p160, Queue: val empty = (nil,nil)

p161, lines 1, 8 and 15. Q should be Queue; structure Q isn't defined until line -11.

p161, lines 7, 13 and 16: No, 'a Queue.queue = 'a list * 'a list, not just 'a list.

p164, line 7 of 19.1: durng

p167, line 18, QUEUE with type ...: QUEUE where type ...

p168, RBT_DTS: missing end

p171, after enumerate: Both forms of ascription also specialize types of values (in the structure) to what the signature requires.

p175, line 6, which types to hold abstract, and which to make opaque: This is phrased as a contrast, but these are the same thing.

p179, 21.1, second sentence: Structure bindings

p180, MyStringDict and MyIntDict, sig ... end: should be struct ... end

p181, MY_GEN_DICT, remove: should be lookup

p181-182, MyStringDict: The code for insert is wrong: the clause that is there is for the case of Empty (not None), and an additional clause is required for the case of a Node. The final case of lookup should be SOME v rather than v. The same errors occur in MyIntDivDict on p182, StringDict on p184-185, LessIntDict on p185, IntDivDict on p185-186, and DictFun on p196.

p185, line 7: Key.eq isn't used. (It could be used when insert is corrected, but it isn't required if you take the equality induced by Key.lt, as in lookup.)

p185, IntDivDict, structure Key : ORDERED = IntDiv: should be DivInt

p189, end of the line that sticks out: Geom2D.Point.Vector.vector

p190, GEOMETRY: In the version near the top of the page, sharing type ... and ... should be sharing type ... sharing type .... In the version at the bottom of the page, sharing and ... should be sharing ... sharing .... [Even in SML/NJ, which implements an extension of SML here, the first version needs to be sharing type ... and type ... .]

p192, line 11, Vector.Point.vector: Point.Vector.vector

p196, lines 7-8 (A functor ... takes a structure as an argument) and lines -7 - -6 (A functor ... whose argument is a sequence of declarations): These are apparently contradictory. The latter is what is done in the rest of the chapter.

p196, DictFun: see comment above on p181-182, MyStringDict.

p197, structures LtIntDict, LexStringDict, DivIntDict: To be consistent with chapter 21, these should be named LessIntDict, StringDict, IntDivDict.

p197, line -1, and p198, line 1, LtIntDict: LessInt

p198, line 5, result signature of DictFun: signature of LtIntDict

p198, line 7, IntLtDict.Key.t: LtIntDict.Key.t

p198, GEOMETRY: This is not the same as on p190, where the last sharing specification is in SPHERE, and this version doesn't go well with what comes below, for instance the sharing spec in SphereFun. Just use the version of GEOMETRY and SPHERE on the bottom of p190.

p198, PointFun: In the elided part, you need

structure Vector = V
or else the application of SphereFun on p199 will not be well-typed after the sharing equations on p200 are added.

p200, GeomFun: sharing and ... should be sharing ... sharing ....

p201, middle, disadvtanges

p203, ExtdGeomFun4, Sp.Point: Ss.Point

p227, line 3 of 26.1, some min N: space missing

p228, line 6, numbers: number

p230, line before 26.3, reverse (t @ [h]): reverse t @ [h]


Don Sannella.
Last modified: Fri Jan 16 09:29:54 GMT 2009