I've tried to read more lately -- where "lately" is maybe the past 2 years -- in an attempt to learn things that I didn't know much about before.

O'Reilly books seem to be the best way to learn about any new technology, because Tim understands that people prefer books that are accessible. I.e., books you can read and understand the first time around, and they don't presuppose a lot of esoteric knowledge. So when I need to learn the latest Algol-family programming language, or Adams-family distributed-computing protocol, or Lisp-family XML technology (Oh no! Now I've gone and let the cat out...), O'Reilly is definitely the way to go.

But for all their great titles, O'Reilly shies away from math, computer science, engineering, general science, and other such impractical nonsense, perhaps because it doesn't sell well. So when I want to learn about something useful but difficult, I need to brave the scary territory of "other publishers".

The Invisible Publisher

Have you noticed how occasionally a publisher will intrude into your consciousness as being exceptionally good (or bad)?

Example: I think of SAMS publishing as being an atrociously bad publishing house. I've bought a few of their titles and have been uniformly horrified at the quality. The books are typically thrown together by multiple authors, each writing different chapters. The authors are evidently unaware of each others' existence, and they often wind up covering the same material redundantly in different chapters -- sometimes even with conflicting terminology or outright contradictions. I just visited their website to make sure it was really Sams, and yep, most of their books have anywhere from two to ten authors. Trust me: just stay away from them.

Some examples of (non-O'Reilly) publishers that come to mind as consistently excellent publishers of technical literature: Um... Oh wait, I know -- I've got it, almost... it's on the tip of my tongue; they're that sort of O'Reilly-like one... shoot. I forget.

Well, I suppose we've got Sun Press and Microsoft Press, but oddly enough, both of them seem to focus mostly on Sun or Microsoft technologies, respectively. So you can't really trust either of them to be open-minded.

Ah, got it! There's that publisher that does the "Hacks" series. You know, Google Hacks, Excel Hacks, Amazon Hacks... they're cool. Oh wait. *Ahem*. That's O'Reilly too. Never mind.

Oh! What about that new "Developer's Notebook" series? That publisher is definitely thinking practically. Like the new Java 1.5 Tiger: A Developer's Notebook -- it's pretty cool, even if the only reason I bought it was to see if you could subclass enums, and the guy asks if any readers have figured out how to do it yet. D'oh. But it's still a cool book. Who publishes that series again?

I'll give ya three guesses; the first two don't count.

O'Reilly is the Starbucks/McDonalds of technical publishing. You know you're getting consistent quality -- not necessarily great quality, but it's consistent. And more importantly, you're getting a consistent experience. You know what to expect. A big, ugly creature on the cover, that's what you should expect. They won't assume you know any math, which is a good thing, because I do all my basic arithmetic using a desk calculator now (M-x calc!). They don't assume anything other than that you're marginally familiar with the English language and that you don't really have much time to spare. Just like Starbucks and McDonalds.

To be sure, there are some publishers whose names (or cover styles) you recognize. Addison-Wesley is a fine technical publisher with some great titles. So is John Wiley. But I had to look on my shelf to remember them. O'Reilly is on a different level; they're a name you bandy about with confidence, knowing everyone else will know them too.

That hasn't happened much in technical publishing. Certainly in Science Fiction, at least when I was a kid, the publishers were important enough that you knew who they were. If Lester Del Rey published a book, then you knew it was going to be great reading for a pubescent teenager -- witness everything Piers Anthony ever wrote, for instance. Ballantine Books were slightly higher-brow, but also excellent. And Daw books, with their distinctive yellow backs, were almost always worth buying. Looking over at my shelf, I see that Enders Game is a Tor book, whom I originally confused with Daw, since I haven't read much sci-fi in the past 20 years. But they were pretty good too, as I recall.

Why is technical publishing essentially dominated by one publisher? (And why isn't Amazon publishing fat orange-and-black Amazon-Press technical books? People would read them, at least for long enough to determine whether they suck or not. We could publish what we don't know about servware and still make a fortune off it.) If I were to hazard a guess, it would be that in order to determine what makes a good tech book, you have to be relatively technical yourself. I get the vague impression that Tim O'Reilly is a guy with a technical bent, or at least with some technical common sense. I've made this point before: you always build great things for yourself, not for other people, or they won't be great.

Ten Great Books

I was originally going to title this blog entry "Ten Wishes", and talk about ten books that I wish I'd read. That is, books I know I should read, because I know they'll be good for me, but I haven't managed to finish them yet. But I thought I'd start off with ten books that I thought were pretty good, despite of all my slobbering-drunken ranting about the relative evils of OOP, multithreading, and von Neumann machines. (Hey, they're sort of what we have to work with now, right? Let my gravestone not read that I wasn't pragmatic...)

With that said, here are ten books that I really enjoyed, and that I'd recommend to anyone who's a computer programmer, regardless of their preferred language and platform. Note: I'm limiting myself to books that I've actually finished and revisit frequently. There are a lot of books that I'm sure would replace books in this list, except that I'm too lame to finish them. I'll write another blog about them at some point.

And with that, the envelope, please...

#1) The Pragmatic Programmer: From Journeyman to Master by Andy Hunt and Dave Thomas.

This is one of my favorite books on programming, although I burned through it in about 3 or 4 hours, and didn't learn a huge amount from it. The point is that it was fun to read, it made a lot of sense, and it was helpful in reinforcing the habits I knew were good ones.

The primary focus of the book is on how to be an effective and efficient programmer, and how to have fun practicing your craft. So, for instance, they'll recommend that you learn how to touch-type with all ten of your fingers. And that you choose a powerful extensible editor and learn how to write extensions for it. And that you use a programming language that supports metaprogramming, so you can code your way out of holes without using hundreds of thousands of lines of code.

Sounds a bit like some of my blogs, doesn't it?

Honestly, though, I worry that the book is somewhat futile. It may be one of those books that you either understand and agree with already, or you never will.

I've sent out suggestions on mailing lists that were more or less directly out of the book, and received responses from so-called engineers who proudly claim, pecking their response out with their index fingers, that they've "gotten by" for 4 years without ever writing a script. Then they mail the same list asking if anyone knows of a refactoring tool that will do a global name-change inside comment headers. Or they'll refuse to listen when the entire community tells them that an identifer name needs to be changed, because it's now "used in too many places". (Yes, I kept those emails; they're in my "broken SDEs" folder.)

Or during a discussion about metaprogramming and code-squishing techniques, someone will just snap, and start ranting about how any OOP book will tell you that EJB is the only thing you need to know.

I'm going to put the book on my Top 10 list in the hopes that there are some programmers out there who haven't yet realized the merits of practicing at being more efficient, and who aren't so set in their ways that the mere thought of learning something new sends them off the deep end into a spittle-emitting rage. It really is a good book, and a fast read. And everything it really does matter, so pay the most attention to the parts that seem to matter the least. Those are the ones you should work on.

#2) Refactoring: Improving the Design of Existing Code by Martin Fowler.

When I read this book for the first time, in October 2003, I felt this horrid cold feeling, the way you might feel if you just realized you've been coming to work for 5 years with your pants down around your ankles. I asked around casually the next day: "Yeah, uh, you've read that, um, Refactoring book, of course, right? Ha, ha, I only ask because I read it a very long time ago, not just now, of course." Only 1 person of 20 I surveyed had read it. Thank goodness all of us had our pants down, not just me.

This is a wonderful book about how to write good code, and there aren't many books like it. None, maybe. They don't typically teach you how to write good code in school, and you may never learn on the job. It may take years, but you may still be missing some key ideas. I certainly was.

The book talks about production code at the level of individual functions, and even snippets of code within a function. It starts by showing you ugly functions that work, then shows you, step by step, how to make them clean and beautiful without breaking them. Some of the techniques are quite powerful, and many can be automated. The book simultaneously showed me why some of my functions had grown large and gnarled, despite my best efforts, and then gave me tools and confidence for fixing it.

The book's examples are in Java, but don't let that put you off. The ideas are relevant for every programming language. I know a guy who read through it without knowing any Java, and immediately began putting the ideas to work in refactoring his Perl code. I even factor and refactor my Lisp code these days.

If you're a relatively experienced engineer, you'll recognize 80% or more of the techniques in the book as things you've already figured out and started doing out of habit. But it gives them all names and discusses their pros and cons objectively, which I found very useful. And it debunked two or three practices that I had cherished since my earliest days as a programmer. Don't comment your code? Local variables are the root of all evil? Is this guy a madman? Read it and decide for yourself!

#3) Design Patterns, by Erich Gamma, Richard Helm, Ralph Johnson, John Vlissides (also known as the "Gang of Four" or just GoF).

This book was incredible. When it came out in early 1995, it offered a set of 23 little reprieves from the blind, crawling, Lovecraftian madness of C++ programming. (Ever notice how "Ph'nglui mglw'nafh Cthulhu R'lyeh wgah'nagl fhtagn" and "Protected abstract virtual typedef'd copy constructor function" sound identical underwater? Yup. The Elder Gods are lumbering and gibbering around Redmond right now.)

Well, it was 22 reprieves, really, since the Interpreter pattern was put in there as sort of an in-joke. 1994, the year the book was being prepared, was in fact the 40th anniversary of John Backus's 1954 observation that most programmers detested the idea of a "compiler":

At that time, most programmers wrote symbolic machine instructions exclusively (some even used absolute octal or decimal machine instructions). Almost to a man, they firmly believed that any mechanical coding method would fail to apply that versatile ingenuity which each programmer felt he possessed and constantly needed in his work. Therefore, it was agreed, compilers could only turn out code which would be intolerably less efficient than human coding..." [John Backus in the 1954 Fortran report]

So true! Compilers are for sissies. Just ask anyone from Geoworks, if you can find anyone left now that they've gone out of business. We all wrote everything in assembly language; it's obvious that computer time is more expensive than programmer time, and good programmers can hand-generate code that outperforms anything any compiler can generate. If-statements and for-loops were for pansies. We had "jcxz" and that was enough.

Most of the programming world who believed that you should write everything in assembly language have moved on (that's a euphemism for "died".) Their children and grandchildren today (that's you!) realize that, well, compilers are pretty important. We'll begrudge them their place. But programmers today firmly believe that any Interpreted coding method such as Java or Ruby fails to apply that versatile ingenuity which each programmer feels he/she possesses and constantly needs in his/her work, etc.

The authors of Design Patterns thought this was pretty funny. The machines change; the languages change, but people don't change. So they threw in the Interpreter pattern as a sort of practical joke, a gag that no real programmers with hairs on their chests would actually understand, let alone agree with.

Other than that, the book was great!

#4) Concurrent Programming in Java(TM): Design Principles and Pattern (2nd Edition) by Doug Lea. Note that I've gone with Amazon's liberal interpretation of the title and dropped the "S" from "Patterns". I'm nothing if not patriotic.

Excellent book on concurrency. Doug Lea wisely steers clear of Quantum Chu Spaces and even basic arithmetic, preferring to focus on "sound engineering principles" that can help your multi-threaded programs run for as long as possible without context-switching. Haha, just kidding. It helps them run as long as possible with context-switching. Jest seein' if yer awake.

Doug really does a wonderful job, at least the second time around; the first edition read like it was by Ph.D's for Ph.D's, which means it was primarily targeted at ineffectual companies like Google. [1] But the second edition is far more manly, hence the cover-art color-scheme switch from cold Vulcan blood-green to manly human blood-red. Really.

The nice thing about this book is that as long as you're using a von Neumann computer, you're going to have to worry about how to fake parallelism on a sequential device, and that's nontrivial. ("Nontrivial" is a computer science term that sounds just like "wgah'nagl" underwater. 'Nuff said.) So even though the subtitle of this book is "in Java", the principles apply to just about any programming language, including Hasturese. Strongly recommended.

#5) Mastering Regular Expressions, 2nd Edition, by Jeffrey Friedl.

Our first O'Reilly title in the list! It has an owl on the front; owls are known for their, uh, regular, erm, never mind. It's not always clear how O'Reilly picks their colophons.

This is a great book for exactly, precisely the reason that all O'Reilly books are great: it covers complex material in a way that's accessible to uncomplex people. Ever notice that "O'Reilly" sounds just like "for Dummies" underwater? And quite frankly, I'm the proud owner of several "for Dummies" books (publisher: IDG, which I believe stands for "IDiot's Guide"); they're very similar to O'Reilly books in their general approach and target audience. It might sound like I'm bashing on for-Dummies books, but quite the contrary -- I hate badly-written, pretentious books that don't talk to me like a person. I've often wished that O'Reilly would publish a Computer Science series.

Anyway, regular expressions are a mini-language for generating and matching regular languages, a concept introduced by the famous linguist Noam Chomsky. A "mini-language" is a special-purpose language with its own jargon and structure. A famous example is StarbucksSpeak, a Turing-complete coffee-ordering mini-language with a rich, free-form syntax and domain-specific jargon, allowing well-formed expressions such as: "Grande quad-shot no-room light-foam half-caf half-decaf half-lowfat half-nonfat 190-degree sugar-free vanilla medium-roast half-white chocolate half-regular chocolate Mocha Valencia with 1 pump sugar-free hazelnut and a sprig of nutmeg. Oh, and make that iced."

As one Starbucks employee put it: "More words means more money." I believe the drink above costs over seventeen dollars. You need to learn the idioms and efficiency considerations for each minilanguage to help optimize its performance.

Other widespread minilanguages include: Pizza-Ordering Language (which has many dialects but is more or less universal), Swearing Like A Drunken Sailor (which is useful when you receive the bill for your car repairs, written in the Auto Repair Theft mini-language), and of course Pig Latin, which is helpful for talking about slower co-workers ("ob-Bay's ot-nay oo-tay ight-bray, is he?"). Mini-languages are everywhere, and can be quite fun.

Regular expressions are no exception. They let you parse a log file faster than you can say: "does Python's case-insensitivity metacharacter span the entire expression, or is that just in Perl?" Like the syntax for printf's format string, regexps are a tool that will be useful in almost any language you use.

Strongly recommended. Oh, and make mine iced.

#6) The Algorithm Design Manual, by Steven Skiena.

This book came highly recommended from a friend of mine who reads a lot (great programmer, too) -- in fact, the same person who was the only one (out of 20) who had read Refactoring, back when I was polling people about it in October of last year.

I've read through most of the book, although I'm not certain I've read all of it, because it's more like an encyclopedia than a continuous narrative. It took me a while to appreciate how useful it is, in part because I wasn't really grokking its organization, which is part narrative, part cookbook, and part bibliography.

But it works! It provides fairly comprehensive coverage of the most common data structures and algorithms, but with a focus on teaching you how to model problems and select the right algorithm. It's filled with "War Stories" and real-life examples.

Most of the examples are wgah'nagl and take several pages of explanation, often with detailed diagrams. If you work through them carefully, you'll gain real familiarity with some useful techniques for solving NP-complete problems. And I have to confess that I didn't fully appreciate how widespread graphing problems are, and how many things can be modeled (and solved) with graph algorithms, until I read this book.

I've read a ton of data-structures and algorithms books, and I've never found one like this one. Its unconventional approach is refreshing and keeps you interested. I find myself coming back to it frequently, and always learning something new.

Summary: this one's a keeper.

#7) The C Programming Language, Second Edition, by Brian Kernighan and Dennis Ritchie.

This is an odd little book. It's frequently mistaken for an introductory programming book, which inevitably leads to frustration. It's not a good way to learn how to program; it expects that you're already familiar with machine architecture, assembly language, compilers, and at least one other high-level language.

It's not even a very good way to learn C. The idioms and best-practices for C programming have evolved substantially, even since the second edition was published, and some of the code samples look a bit dated.

However, with all that said, it's still an amazing little book. The C language is a remarkably elegant balancing act between efficiency and expressiveness. By today's standards, perhaps, it doesn't seem very feature-rich, and many people feel that programming in C can be tedious. Perhaps so. It depends, I think, on the size of the system you're trying to build, and on your overall familiarity with the language and tools.

C isn't really suitable for building huge systems, but it was never intended to be. C was created for making Unix, and Unix isn't a large system; it's a large collection of small systems that work together cleanly and effectively (for the most part).

C is an elegant language, and is in my opinion quite a breath of fresh air if you've been working in C++ for very long. People who try use C++ to build giant, hairy systems often wind up being giant, hairy programmers as a result. If you're trying to build a large system in C, you'll inevitably wind up making a choice between two alternatives:

Use the AlternateHardAndSoftLayers design pattern, in which you write most of your code in a high-level language, and the performance-critical parts in optimized C. Try to make C a high-level language itself, which either leads to the madness of choosing C++, or the madness of implementing your own high-level language in C, without any actual syntactic support.

Most companies choose the second option, usually because they haven't learned the hard way that 90% of your code never needs to be optimized, and doing so won't produce any human-observable difference in runtime performance.

Java is essentially a pre-packaged, turnkey solution for option #1; hence it has all the pros and cons of a turnkey solution. It's easier -- you only have to learn one language, and you can avoid most of the low-level programming and porting issues. The downside is that you're not using a true high-level language, and it's not as easy to optimize the performance-critical parts. But on the whole, it's better than trying option #2.

When it comes right down to it, though, C is a beautiful little language. Many (most?) computer games these days use the AlternateHardAndSoftLayers pattern; the game engine is written in C, and the games themselves are written in higher-level languages. And the game industry is one of the most obsessively performance-focused software industries out there, so that's pretty strong evidence in favor of that pattern.

I guess what I'm trying to say is that writing in C is a pleasure, as long as you don't try anything too ambitious by yourself. And the K&R book may just be the best way to see this. It's certainly a great way to come back to the language after you've been a way for a while.

Summary: after a long hard day of C++ programming, it's nice to revisit something simple and elegant.

#8) The Little Schemer, by Daniel P. Friedman and Matthias Felleisen

This is without question one of the weirdest technical books you'll ever encounter. But don't be put off by the format. Well, you WILL be put off by it, but try not to be dogmatic about it.

This book makes my top-10 list because it helped me understand recursion and think recursively better than any other approach. Scheme is a fine language for doing this, although they could probably have just as easily done the book in Haskell or Ruby. It doesn't matter, though -- the concepts transcend the language.

A lot of people simply avoid recursion because they've heard it doesn't perform very well. They don't practice it, so when they run into situations where recursion is the most natural approach, they have a LOT of trouble with it.

Recursion is the most natural way to express many algorithms, including tree and graph traversals, linear and dynamic programming, parsing of computer languages and natural languages, and plenty of others. If you aren't comfortable thinking recursively, you'll tend to steer clear of recursive solutions, which means that for many problems you'll wind up with code that's a lot uglier and error-prone than it should have been.

The Little Schemer is not a book that you can sit down and read like a novel, or even like a J2EE technical manual. You have to work through all of the examples yourself, by hand, in order, and you can't skip any of them.

The painful way (IMO) is to use a Scheme interpreter; I found it easier to translate the examples into Emacs-Lisp and run them in lisp-interaction-mode. There are only a few simple rules to remember. Or perhaps you can find a Scheme plug-in for your favorite editor. However you decide to do it, you need to do it -- you have to solve the problems yourself.

They recommend that you don't try doing the book all in one sitting; it has about 10 chapters, and I was doing about 2 a day, so I got through it in about a week (about an hour a day).

About halfway through, you really start getting the hang of it, and by then they're mostly teaching you common idioms for recursion. If you really do the examples, it gradually becomes fairly trivial to express things as singly- or doubly-recursive functions.

I haven't made it through the Seasoned Schemer yet -- that'll undoubtedly be in my "Ten Wishes" blog entry about books that I want to read. But I'm looking forward to it.

Summary: wonderful book. Definitely deserves a spot in my Top 10 list.

#9) Compilers, by Aho, Sethi and Ullman

This is the (in)famous "Dragon Book", and it's by far the hardest book in the list so far, even more so than The Algorithm Design Manual, in no small part because it's extremely dense. That, or I'm extremely dense. Or both.

However, all the other compilers books I've tried out have been unsatisfactory. We used this one in school, and I pretty much hated it. Every few years I'd pull it out and try to puzzle through it, and it would put me right to sleep. Wonderful soporific, for those of you with occasional bouts of insomnia. The authors have evidently released a new version in C (the old one was in Ada), and maybe it's gotten better, but I haven't looked at it.

After several years of fighting with the Fisher and LeBlanc book, I finally bought myself a copy of the Dragon Book. I'd heard the most awful horror stories about it, so you can imagine this was an act of sheer desperation. And much to my surprise, I found it to be a wonderful book.

I can appreciate the arguments to the effect that it's not a good text for undergraduate students. But that's clearly not the intent of the book. The book was obviously written for the educated researcher or working professional who wants to write a compiler, and doesn't want to mess around. It covers virtually all of the issues known to compiler writers at the time it was published, except for some of the fancier optimization techniques. I have no doubt that Richard Stallman possesses a dog-eared copy, and so do the teams that have built virtually all production-quality compilers in the past 20 years.

I'm going to argue in a yet-to-be-published essay that Compilers and Operating Systems are the most important courses in an undergraduate CS degree, and that both of them should be required for graduation. Unfortunately I don't know of any CS degrees that require them both; usually they let you get by with one or the other (or neither).

Suffice it to say for now that a working knowledge of compiler construction is the thing that differentiates good programmers from average ones, and expertise with compilers is something you find in all great programmers. Even if you never plan on writing or working on a compiler yourself, it's still the most important CS subject, and it's a damned shame that most schools don't tell you how and why it's so important.

There are other books on compilers, and you'll probably need to struggle with many of them before it all starts to really come together. Compilers are among the most complex programs a person can write, and it's taken fifty years for the world to figure out as much as we know about them -- which isn't enough by a long shot, but the situation is improving.

But I think once you've really started to master the subject, the Dragon Book is the one you'll keep coming back to. So it makes the list.

#10) WikiWikiWeb, by Ward Cunningham and thousands of others.

I got tired of scanning my shelf for important books. Most of the books on my shelf are either (a) really important, but I haven't finished them yet because I'm a loser, or (b) not very good. There are very few that I'd recommend for all programmers, except for textbooks, and I've already got two or three pretty hefty books in my list so far.

The WikiWikiWeb (also confusingly called the "Portland Patterns Repository") is the world's first and oldest Wiki. It's also one of the larger ones, although it's peanuts compared to Wikipedia, which has nearly 400,000 exceptionally high-quality articles, and 3 ugly ones. Its sister projects (WikiDictionary, etc.) are no slouches either. The Wikimedia Foundation sites are rapidly becoming some of the most important intellectual hubs on the internet, notwithstanding the fact that the founder's name is Jimbo.

But WikiWikiWeb is still cool, and in particular it's cool because it has a lot of smart people agonizing over hard issues. Strong typing or weak typing? OOP, functional style, both, or neither? Pair programming or no? The site has thousands of useful explanations and interesting discussions. It's one of the very few internet sites that I keep coming back to, and it's been just as valuable to my education as a programmer as any book I've read, so I think it gets a spot in the list.

Epiblogue

I had myself a wee bit too much vintage port tonight, and I'm now at the point where I'm making up words like Epiblogue, so it's clearly getting time to call it quits.

Tune in next time for my far-more-interesting list of books that I know are truly groundbreakingly fantastic, since I've read anywhere from a chapter to half the book, but I'm too stupid to finish them. Or in some cases, I just found out about them, and I'm racing to finish them as fast as possible.

Would love to hear comments or pointers to other peoples' favorite-books lists. I'm always keeping my ear out for recommendations.

(Published Nov 18th 2004)

Notes

[1] I work at Google now; I hope they realize I was being facetious.

Comments

"I'm going to argue in a yet-to-be-published essay that Compilers and Operating Systems are the most important courses in an undergraduate CS degree, and that both of them should be required for graduation. Unfortunately I don't know of any CS degrees that require them both; usually they let you get by with one or the other (or neither)."

UIUC requires both.

Posted by: Joel H. at November 19, 2004 01:22 AM

I highly recommend _Expert C Programming_ by Peter van der Linden. It addresses a lot of esoteric issues related to C, like the difference between pointers and arrays and how to parse declarations like:

char * const *(*next)();

Despite tackling rather dry subjects, the book is extremely readable. It is a delightful blend of substance, anecdotes, folklore, and programming challenges. I actually ought to re-read this book; I whizzed through it too fast the first time, and I'm sure I could get a lot from a second reading.

I really ought to put a category on my weekly timecard for "Reading Steve's blog." How do you get the time to write all this stuff?

Posted by: Josh H. at November 19, 2004 01:37 AM

I think you mean /approximating/ the answer to NP-hard problems :)

Didn't like Knuth or _Structure and Interpretation of Computer Programs_?

Skiena is a lot easier and more useful day-to-day than Knuth, I admit.

Posted by: Andrew W. at November 19, 2004 02:28 AM

Sorry Andrew -- yeah, 'approximating' is probably a better word. You *can* solve (some) NP-complete problems, of course. But I meant "solving" in the more general sense of "figuring something out so I can get my business problem solved". Anyway, fair point.

I never really cared for _SICP_. There are plenty of other introductory programming books that use Scheme. This one, for example, but others as well. But I suppose I could give SICP another chance. [Note, 12/13/2004 -- I went ahead and gave it another chance, and I was way wrong. It's awesome. I'm putting it into my Ten Favorites list that I'm going to publish soon.]

Knuth is awesome. He's a great writer, very warm and funny. And his books are (oddly enough) always beautifully typeset. I just haven't finished any of his books yet. I'm about halfway through about five of them at the moment.

Josh: I type fast. :) And I have a lot of notes lying around. I like to type while I think. (I even have a partially sketched-out essay about how useful that is.)

Posted by: Steve Yegge at November 20, 2004 12:13 AM

Joel: UIUC rocks! No wonder we get so many great people from UIUC.

Anyone else know of CS programs that require both Compilers and OS?

Posted by: Steve Yegge at November 20, 2004 12:14 AM

Stray thoughts on the publishers:

My own experience with O'Reilly has been a long ways from consistent, but then again I was one of those guys who bought every single O'Reilly book he could find for a good couple of years. There's bound to be some stinkers in there somewhere. My O'Reilly books still tend to be pulled down from the shelf most frequently.

Sams is making a bold attempt to put the whole "Teach Yorself Cp+ in twenty-1 Days" titles and typographical infamy behind them. I've been pleasantly surprised by a lot of their newer books - the ones with the purple covers. Still not great, but better than bad.

Addison-Wesley publishes the books that I have on the shelf to impress folks. The ones that I've been able to afford are impressively dense and heavily laden with tons of valuable insight. I read and reread Stroustrup's C++ Programming Language (2nd edition, still haven't made my way to the 3rd), and got lots of knowledge every time, occasionally sprinkled with a mild headache.

Oh, and I'm not sure if you noticed, but four of your top ten books are published by Addison-Wesley, and only one O'Reilly book is on there. Maybe it's just my interpretation of chance numbers, but the interpretation matches my own thoughts: Addison-Wesley publishes the best, but O'Reilly publishes the ones we actually use.

Actually, I may have to take that back. The book closest to my keyboard right now is "Effective Perl Programming", published by Addison-Wesley.

Oh, and there are a couple of decent publishers who should get mention. Manning has published not only "Object-Oriented Perl" by the fiendishly clever Damien Conway, but they have also released the only Perl book I've ever purchased for other people interested in the language: "Elements of Programming in Perl". Twice. The book that I'm never going to write about Ruby would be modelled closely after that one. Man, I'd love to see a second edition of Elements.

And New Riders. Mostly bland run-of-the-mill stuff comes from their presses, but they occasionally release a book that makes you feel like you needn't bother buying anything else on the subject. Right now I'm thinking of David Beazley's "Python Essential Reference", but there were others.

Dang. A reply that may as well have been a blog post on its own. Ah well, I guess the coffee is good today.

Posted by: Brian W. at November 24, 2004 07:34 PM

Practical Software Requirements: A Manual of Content and Style

Posted by: Derek U. at November 29, 2004 08:22 PM

Applied Cryptography

This book is a very good overview and introduction to security and cryptography. It's geared towards engineers rather then cryptologists which makes it much more useful to and SDE. It can be a bit of a difficult read considering its nearly 800 pages on what most people consider a dry topic, but the author writes and a very readable and entertaining style so it's not too bad. Considering that cryptology and security is something that every SDE who considers himself an engineer should be more proficient with, it's definitely worth the effort required to read it.

Language Processors For Little Languages.

This is another very good introductory book. It's geared towards the development of Domain Specific Languages. This book is also a bit less intimidating then the venerable Dragon Book.

I wouldn't put either of these books into the top ten. However, I do consider both of these or their equivalents required reading for any SDE worth his salt. Of course, there are quite a few other areas an SDE needs to be grounded. I pick out these two simply because they are two areas and SDE should be familiar with and, generally, are not.

Posted by: Eric M. at December 1, 2004 07:46 PM