Every year as I wade into reviewing books for the Jolt Awards, I am forced to slog through several language tutorials. Over the years, I've found them to be reasonably well written, although rarely more than this. That is, they're accurate, and a determined reader can certainly learn enough from them to code in the target language. But I am hard-pressed to be more complimentary for even the best tutorials.
These books are marked by common failings that greatly frustrate their simple mission. The first and by far most-common handicap is a confusion by the authors in which they conflate a tutorial with a detailed treatise on every aspect of the language. For reasons not quite clear, the latter approach seems generally favored by the publishing industry, resulting in almost ridiculous volumes. I have in front of me a 1480-page "introduction" to Java. The notion that anyone would read that many pages as a primer defies credulity. Predictably, the book descends into the AWT and Swing, pops up to diverge through tributary libraries, disappears into the VM, and finally ends up in parallel programming, after which it thankfully comes to an end. Given that this particular volume is the 4th Edition of this title, I have to believe that it represents the ultimate in refinement of the author's intended model. It's really a hybrid tutorial-reference work. And my guess is that since it weighs 4½ pounds, it serves primarily in the latter capacity. Mark Lutz's Learning Python is that language's equivalent of this book. Other tutorials, such as the "Pickaxe book," which brought Ruby to the attention of the Western world, unabashedly follow this model. The front half is tutorial, the back half is marked as reference. This approach works far better. And the quality of the Ruby tutorial, despite its length (418 pages), justifies the popularity the book has enjoyed.
Another common failing is that the authors forget what readers most want to do when learning a new language; namely, to write small working programs to familiarize themselves with the syntax. Frequently, tutorials present endless tiny snippets of code that illustrate a feature without showing a single useful program. This tendency is greatly exacerbated if the language has a built-in shell/interpreter, as is the case with Ruby, Groovy, and Scala.
For example, the Scala tutorial by Odersky, Spoon, and Venners (Programming in Scala) is a fair representation of the problem. In the first 200 pages, I was able to find only one example longer than 20 lines of code; the majority being less than 10. (In K&R, which I'll come back to in a moment, the first 20-line program appears on page 26.) The result, as I experienced it, was that after a lot of reading and typing, I knew a little bit about a lot of features, but still had not written a single program that actually did something useful. To be fair, this problem is strikingly common. I have tutorials on Clojure and Groovy before me that proceed exactly the same way.
Finally, a pet peeve that I find frequently in poorly edited tutorials: the desire to show off the language by presenting clever tricks or small hacks it can accomplish. Personally, I want to learn, rather than watch linguistic parlor tricks. This weakness shows up most frequently in tutorials for functional languages and for those, such as Groovy, where the syntax is purposely designed to be better than a competing language (in this case, Java).
The truly frustrating aspect of all three limitations is that there has long existed a brilliant tutorial to serve as a guide: Kernighan and Ritchie's C Programming Language book (K&R). Judging it beside other tutorials, the differences are immediately visible. Let's start with the obvious things: the tutorial portion of K&R is a mere 177 pages. This is followed by 40 pages of appendices, which serve as a highly abbreviated reference section. At this modest length, any reader can work through the book and do all the examples. Secondly, most of the programs are longer than 20 lines, do something mildly useful and familiar, and are complete. Even 125 pages into K&R, an illustrative program has a main() function. We're not talking snippets here, we're looking at real, albeit short, programs. Finally, the explanations are lucid and they build incrementally on each other. They do not present a scattershot of features. There is a pervasive sense of sequence; and at all times the reader knows where he is in relationship to the ground covered and the ground yet to be traversed.
What is missing from K&R? Most clearly, it lacks a section that explains every function in the standard library. Java books should drop this nonsense, too. (The definitive books on all the arcana of Java, including the library and solving knotty problems, is the lapidary Core Java, Volumes I and II, by Horstmann and Cornell. But at a combined 1800 pages, they do not comprise a tutorial nor, I might add, do they claim to).
The second thing K&R omits is spoon feeding. You have to think as you work through it. All the information is there, but you're forced to engage the language through the examples to get what you need. The authors expect you to be an attentive reader. As a result, you can move quickly through the language because the book supports you, rather than forcing you to read pages that add little to your comprehension.
I want to make clear that the books I named were chosen with care because they are, in my view, the best tutorials for their respective languages. Odersky et al. on Scala, Thomas on Ruby, Lutz on Python these are the best starting points for their respective languages. I only wish they'd followed K&R's model more closely.