When I first heard that this book was going to be published a few months ago, I was admittedly quite intrigued. OCaml is the primary language I use both at work and at home, and so I viewed anything that might boost the number of users of OCaml as a good thing. And since this book was part of the series of books that contains Peter Seibel's Practical Common Lisp, a well regarded book that re-introduced Lisp as something more than a relic of bygone days, useless to all but the "smug weenies" of the world, I had high expectations for it. After being pushed back a few times, the publishing date finally grew near, and I had become quite anxious to get my hands on a copy. So when it finally arrived, I pulled it from the package, cracked it open and
The look and feel:
The first thing that I noticed (and this is almost never a good thing in publishing) is that the typography is awful. Code listings are haphazard in appearance, with no apparent sense of indentation. All of the listings look as if they were simply cut and pasted with no effort made to reformat for the page. Occasional bold text and odd glyphs appear in the code listings for no apparent reason, and on top of that, the font size for the code was fairly large; larger than the main text. This is perhaps good for those with failing vision, but it effectively narrowed the page for the code examples and led to unnatural looking listings. A quick glance at many of the programming books in my office shows that other publishers seem to agree with me that a smaller font should be used for code than for the main text.
This may seem like a trivial complaint, unfortunately, it makes the code look astonishingly ugly, almost painful to read. And this is not a good thing if you are trying to interest people in looking at the language. Perhaps the fine people at Apress may wish to read this bit of wisdom from the manual of the Memoir Class for LaTeX:
"However, just as writing is a skill that has to be learned, typography is also an art that has to be learned and practised. There are hundreds of years of experience embodied in the good design of a book. These are not to be cast aside lightly and many authors who design their own books do not know what some of the hard-earned lessons are, let alone that what they are doing may be the very antithesis of these. An expert can break the rules, but then he is aware that he has good reasons for breaking them.
The author supplies the message and the typographer supplies the medium. Contrary to Marshall McLuhan, the medium is not the message, and the typographer's job is not to intrude between the message and the audience, but to subtly increase the reader's enjoyment and involvement. If a book shouts 'look at me!' then it is an advertisement, and a bad one at that, for the designer."
I started by reading chapter six, "Primitive and Composite Types" first, because this is the sample chapter available from the book's website. Chapter six is supposed to be an in-depth look at types in OCaml, and it begins well enough, starting with an example of why type safety can be important, and mentioning that OCaml differentiates between ints and floats; then thing start to go awry. Smith wrongly claims that OCaml only offers the int64 type if 64-bit ints are supported on your system, and follows with a poor description of the nativeint type. Then, after making clear the differences between ints and floats in OCaml and discussing them in separate sections, Smith confusingly combines chars and strings — two separate types in OCaml — in the following section. Adding to the confusion, he introduces chars by saying that they are ASCII values that can be defined by '\<NUMBER>', e.g. '\001', but doesn't mention the standard way of working with printable chars, e.g. 'A' rather than '\065' until you see it in some code on the next page, (in addition he doesn't mention the hex version either, e.g. '\x41').
He then shifts course for no apparent reason, mentioning the Pervasives module in a way that has nothing to do with types, before bringing up lists and arrays, and then reverting back to talking about the built-in primitive types by writing about exceptions, bools, and lazy types (somehow neglecting to cover the unit type or references in the process). It's at this point that the book gets even more confusing. Smith then launches into a discussion of polymorphic types via the use of variants. This wouldn't be so bad if he a: explained the syntax being used to the reader, and b: bothered to cover variants earlier in the section, or at least offered up a reference to his brief introduction to them in chapter three. Skimmers of the book, or readers of the sample chapter are sure to be left baffled. He then concludes the chapter with a confusing section on composite types, and a section on polymorphic variants which should have either warranted a full chapter covering their use, or been left out of the book entirely as their use can be tricky to master.
Note that I went into such depth in chapter six because it really is a representative of the quality of the rest of the book. The poor organization and flow, the shallow coverage of the core concepts of OCaml, and a seemingly shallow understanding of the language by the author. These flaws pervade the entire book: In chapter two, Smith attempts to show the interactive toplevel presenting the user with a type error. Unfortunately, his example requires the definition of a type distance, that we don't see until the next chapter, so if the reader tries to type the example into the OCaml toplevel, they will see a different error message than the one Smith shows; In chapter three, he brings up theorem proving and the Coq proof assistant for no good reason, and then never mentions them again; In chapter four, "Understanding Functions", a section on using lists appears between sections on higher-order functions and anonymous functions, as if it were dropped there by accident. Pick a chapter, any chapter, and you are likely to find concepts used before they are introduced (sometimes full chapters before they are introduced), and off-topic asides that serve only to hinder the flow and to confuse the reader.
But if poor flow were the only problem with this book, the reader may still find it useful for learning the language. Sadly, it is not:
- Core, fundamental aspects of the language are covered far too lightly. Pattern matching, considered to be one of OCaml's great strengths is introduced with just four lines of text and five lines of code, and is barely expanded on later in the text. Variant types (used heavily with pattern matching) are also given all to brief coverage, and his complete lack of coverage of functors when introducing the Set and Map modules is sure to leave a reader shaking their head in frustration (to be fair, Smith does mention that they will be covered five chapters down the road, but even there his explanations fail to explain the subject in any useful way).
- Terminology and concepts are repeatedly abused. For example, Smith often conflates types with members of a type, and his explanation of Curried functions is almost cringe-worthy.
- Many of the code examples are useless, like his bizarre addition of a recursive type member to a distance type (he should have just saved that notion for the much more natural and useful definition of a tree type that follows immediately after), or his definition of min and max functions for use in a spam filter, rather than just using OCaml's built-in min and max. Other code examples are simply poorly written for an educational text. E.g. he uses Hashtbl.fold (fun x y z -> blah) rather than the more informative Hashtbl.fold (fun key value base -> blah), which at least cues the user as to what the code does. As it is, his code more or less requires the reader to have a copy of the standard library documentation handy.
Another example that pretty much sums up the author's examples is his version of a rot13 translation function. His code:let trans_file c =
match c with
let nc = Char.code c in
let b = (nc + 13) in
if (b > 122) then
String.make 1 (Char.chr (96 + (b — 122)))
String.make 1 (Char.chr b)
let nc = Char.code c in
let b = (nc + 13) in
if (b > 90) then
String.make 1 (Char.chr (64 + (b — 90)))
String.make 1 (Char.chr b)
| _ -> String.make 1 clet trans_file c =
(match c with
| _ -> c)
- But most egregious of all the problems with the book is that Smith either has a fairly shallow understanding of the language, or just an inability to transfer his knowledge to the reader. As with the other issues, this can be seen throughout the book, but the example that stuck with me the most comes from his discussion of the type t in his module signature for a URI library (coming two full chapters before his coverage of modules, of course). In his explanation, he states that "it is a special type that represents the type of the module itself." This is not so: t is not a special type at all, but rather a convention used by the creators of OCaml and members of the OCaml community, and is like any other user-defined type. It is also not a representative of the module type at all. What it usually is, is simply the type of the primary value associated with a module, e.g. the data structure that holds the entries in a hash table. Finally, the type t is usually used as an abstract type of that primary value, hiding the actual concrete type from the users of the module, preventing them from working with the value in any way other than via the functions provided by the module. Smith does not follow this convention, exposing the concrete type of t for the user to see and manipulate directly.
With all of these problems (and a healthy list of typo style errata), I simply cannot recommend this book to anyone except perhaps the OCaml completist. It will not help you learn the language in any meaningful way, and it will likely result in nothing beyond confusion.
In truth, it makes me sad to have written this review. I really don't like speaking ill of another man's work, and I would have loved to have seen a quality book on OCaml sitting on bookstore shelves. And if this review were to keep people from buying the book, it may lead the publishing industry to believe that there's no market for an OCaml book at all, while there may very well be a market for a good OCaml book. Still, I would feel worse if somebody were to spend their cash on this book only to come away bewildered, and perhaps with an unfairly dim view of OCaml. You're better off saving your money and looking at some of the free resources on OCaml instead. Jason Hickey's excellent introduction to OCaml (link goes directly to a pdf), and the somewhat outdated, yet still very useful translation of Developing Applications With Objective Caml are perhaps the best places to start, in conjunction with the ocaml mailing lists. Also quite useful is Richard W. M. Jones' OCaml Tutorial wiki. As a closing note, Richard, a respected member of the OCaml community, served as the technical reviewer for Practical OCaml, and he wrote an interesting note on his view of the process from the inside."