Books Programmers Don't Really Read But Recommend
billthelizard.com
billthelizard.com
K&R was my second C book, and I love it for its authenticity, but I learned more from Kelly & Pohl's "A Book on C".
The Mythical Man Month I read in anger after a project failed. It not only resonated with me, but cheered me up.
Programming Pearls can't be "read" in the usual way, it's something I flip through when facing particular problems, but generally I savor it (ended up selling my copy after my 2 year backpacking trip, back when I swore I'll never write software again .. oops!)
Effective Java (C++) are practitioner lore. Their teachings have been subsumed by the language community and you can see it in code bases.
My advice is to learn to use your favorite editor with a TAGS file, then go navigate through a large open source project, and extend it in some minor way. That's more profitable than enduring any book on "design".
I never cared for "Pragmatic" or "Test-driven" or "Agile" publications.
This is the truth.
On the other hand, I learned from experience that people do not take this advice when you give it. Maybe plunging into large codebase is daunting, I don't know. Now I give them http://www.aosabook.org/en/ and tell them to choose an interesting project and then read it.
Their follow up book also looks good: http://www.aosabook.org/en/makingsoftware.html
I also recommend "Rapid Development", by the same author. It sounds like a fuzzy, Agilish cliche, but a more accurate title is probably "How not to fuck up your project." All of the usual bugbears are there - technical debt, creeping requirements, gold plating, etc.
Eh, I don't recommend Code Complete, either, though not for the same reasons as mahmud.
You say you don't know of a book "which cover the nuts and bolts in such a thorough way". I can name one that covers almost the same territory:
Kernighan and Pike's excellent The Practice of Programming.
You could certainly argue that it doesn't cover the same territory in such a "thorough" way, if by thorough we mean "needlessly bloated". The Practice of Programming manages to say, in 288 pages, everything useful that McConnell needs 960 pages to spit out.
The Practice of Programming is the last book I can think of that came out of the old tradition of software books that valued concision and clarity of communication above all else. It's short and precise in the way that "The C Programming Language" is short and precise compared to modern PL books. Code Complete is a product of modern software book marketing; it takes forever to say anything, so that it consumes maximum space on a bookstore shelf, and attempts to justify its price in weight rather than ideas.
That said, I'm going to have to find a copy of it now and compare them :)
The Art of Readable Code (by Googlers)
http://www.amazon.com/Art-Readable-Code-Dustin-Boswell/dp/05...
The code examples in The Practice of Programming are atrocious, and I mean it - they are full of really, really bad naming and arcane abbreviations and thus unreadable code.
How is this for readable and maintainable code? (Random code example from The Practice of Programming, copied verbatim letter by letter)
/* delname: remove first matching nameval from nvtab */
int delname(char *name)
{
int i;
for (i = 0; i < nvtab.nval; i++)
if (strcmp(nvtab.nameval[i].name, name) == 0) {
memmove(nvtab.nameval+i, nvtab.nameval+i+1),
(nvtab.nval-(i+1)) * sizeof(Nameval);
nvtab.nval--;
return 1;
}
return 0;
}
- Confusing function explanation in a custom format. What is nameval? What is nvtab?- Missing curly braces in the for loop
- Confusing long lines (line starting with memmove())
- Confusing inline transformations: nvtab.nameval+i+1, nvtab.nval-(i+1) directly in function arguments. What do they mean?
- Bad, bad naming (nvtab, nameval)
- Inconsistent case (nameval vs Nameval)
This is just ONE RANDOM EXAMPLE, mind you. The book is atrocious, I don't recommend it to anyone.
Code Complete is much thicker but that's the only disadvantage. It's not bloated, it's simply more comprehensive, it's consistent and teaches to write actual readable code.
- Confusing function explanation in a custom format. What is nameval? What is nvtab?
nvtab is obviously a name/value table. nameval is an array of Nameval structures. nval is the count of Nameval structures in nvtab.nameval.
- Missing curly braces in the for loop
This isn't required by C. It's an often-debated subject in style guides for C.
- Confusing long lines (line starting with memmove())
How is that confusing? Lines end when you see a ; that isn't inside a set of parens.
- Confusing inline transformations: nvtab.nameval+i+1, nvtab.nval-(i+1) directly in function arguments. What do they mean?
What do you mean, "what do they mean"? (int)-((int)+1) seems pretty obvious. Working with memory addresses doesn't seem a foreign concept.
- Bad, bad naming (nvtab, nameval)
nvtab seems like a reasonable name for a name value table. nameval seems like a reasonable name for something that holds a bunch of Nameval structs.
- Inconsistent case (nameval vs Nameval)
nameval and Nameval are different. If you used consistent case, the program wouldn't work. nameval is an array containing Namevals. Nameval is a struct.
This just seems like a case of you not really understanding C rather than a case of experienced C programmers writing C that other C programmers could maintain.
Perhaps this is the effect that high level languages are having on developers - anything that DoesntHaveExplicitNames is classed as confusing and syntax flexibility is seen as wrong. In the web development field, I often get weird looks for writing one line if statement bodies. A ternary operator usually yields furrowed eyebrows for a few seconds. An issue of style over substance, IMO.
Then again, I'm sure that ASM developers looked at C developers the same way.
Speaking on naming conventions: This is the name of a class in Chromium source code (C++): 'BufferedSpdyFramerVisitorInterface' . The codebase is that meticulous! For a guy who wanted to learn about browser implementation,and downloaded the codebase,this is good.
These meticulous naming conventions- has it anything to do with using a full-blown ide vs vim?
What would you think that?
If it's because of auto-complete, please understand that this is 2012, and vim is not [just] vi. There are several different flavors of auto-complete available in vim; some built in, some as extensions.
I don't think you need much more evidence that the syntax is confusing.
That typo was introduced in Revisor's transcription; it doesn't appear in the original. I checked when I first read his comment, 8 or 9 hours ago. It hardly seemed worth mentioning; typos happen and it had nothing to do with his argument.
> I don't think you need much more evidence that the syntax is confusing.
Someone unfamiliar with the language introducing a one character typo during a character-by-character transcription from a book is evidence that "the syntax is confusing"?
What an odd yardstick to use.
Now if you put each argument on it's own line, or use reasonable variable names - something that C programmers seem to fight against - neither of those bugs happen, because you can just look at the code and see the problem straight away.
memmove(nvtab.nameval+i, nvtab.nameval+i+1,
(nvtab.nval-(i+1)) * sizeof(Nameval));
Experience C programmers will know memmove - it's been a long time since I even saw the signature, but I thought it was going to be source, destination and size. (Looked it up just now to be sure.) These "inline transformations" are common on addresses in C.I personally like braces around for loops, but things like Nameval being the struct type for a nameval variable is common C practice.
> Confusing function explanation in a custom format.
It's a straightforward explanation in 6 words of English of what the function does. That's not a "custom format", that's a simple and concise introduction to the function. Far preferable to some mess of nonsense boilerplate XML.
Also worth mentioning is that in the context of the book that function sits in part of a larger discussion which, IIRC, gives the definition Nameval struct (that's definitely not some kind of accidental case flub), talks about the structure of nvtab, etc.
Defend it all you will (and also downvote just because you disagree, why thank you), I stand by what I said: The Practice of Programming is a harmful book and cannot be compared to Code Complete which is much more thoughtful and has unspeakably more attention to detail in naming, syntax, logic, programmer's psychology, project scope, everything.
Apart from using braces for `for` loops, yes.
> Fourfold inline computation?
This snippet
void *dest = blah blah;
void *src = blah blah;
size_t cnt = blah blah;
memmove(dest, src, cnt);
isn't any different from memmove(blah blah, blah blah, blah blah) if you program in C. Introducing unnecessary noise doesn't contribute to code clarity.> Cryptic variable names like nvtab.nval?
Suggest a better name. name_value_table.number_values? And give me one good reason how is this better?
There is a whole camp up in arms against abbreviating `count` as `cnt`. Though they never told me what issue they have understanding that `cnt` means `count`.
The only issues I have with abbreviations is they might introduce typos if you choose confusing ones. nval, nvtab etc aren't confusing, not by a mile. If you are confused by them, expanding them isn't going to help you either.
> Comments that use deep local jargon (what is nameval, what is nvtab)?
A localized code snippet uses local jargon. If you disagree, I would love to see your suggestions on improving them.
> Defend it all you will (and also downvote just because you disagree, why thank you), I stand by what I said:
Apart from standing by, show us how do you make it more readable. Your complains so far are fluffs.
> The Practice of Programming is a harmful book and cannot be compared to Code Complete which is much more thoughtful and has unspeakably more attention to detail in naming, syntax, logic, programmer's psychology, project scope, everything.
Sounds like Code Complete is programming for people who can't program.
I have to admit I thought it worth the time to read. It is an easy read. There are certainly books on this list that provide >10x the value, but take >10x the effort to assimilate.
>> It tries to teach stuff that is best learned through experience.
Experience is a harsh teacher.An engineer building a bridge doesn't have an easy way to just try it out. Someone hacking together something at home, or an internal facing product at work can learn by experience.
If this were a book, it would probably go on the "Books Programmers Claim to Have Read" list.
I was about to say the same exact thing, but was too afraid to because of the backlash.
That book has little to no use. It's a book you would give to someone that's a -1 level programmer on a 1 to 10 level scale, to bring him up to a 1. Really, it is.
I've always wondered if its recommended because people were not reading it, or if there is a case of general incompetence (the type that would get you fired, or not hired) in the general programming pool.
I totally agree about Design Patterns. That is perhaps the driest (I mistyped that as "direst"; Freudian slip?) technical book (or any book for that matter) I have ever tried (and failed) to read.
Thing is, technical books don't have to be that way. The early Michael Abrash books (eg [1]) are actually highly entertaining. Effective C++ and Java are eminently readable.
I lot of people recommend CLRS and I've certainly studied from parts of it but I found Skiena's The Algorithm Design Manual to be far more approachable and enjoyable. If your goal is to learn I suggest that. CLRS seems more aimed at people who want or need to know mathematical proofs or are bound for postgrad CS.
TAOCP and the Dragon book are classic examples of books that get recommended all the time (on SO, here and elsewhere) but I'm convinced only a handful have actually read them.
[1]: http://www.amazon.com/Zen-Assembly-Language-Knowledge-Progra...
The Dragon book I still own, a paperbound version that's as dog eared as a book can get and still hang together as it was the reference for three of us working on a few compilers of our own back in the day.
The C Book I no longer have despite having bought four to five copies :( That book's never been much of a boomerang.
(BTW: I didn't find it all that interesting conceptually, they're the solutions you'll come up with yourself, just collected and named and categorized. Reading how they solved specific problems was interesting - vicarious experience - though some seemed more whimsical than workmanlike.)
If you can, find on github some idiomatic code for whatever language you're trying to learn (and take it with a grain of salt -- Spring Framework, for example, has good code in it, but you'd never need to make your solution so complicated because your code doesn't need to be extensible by everyone and their little sister).
http://www.amazon.com/Core-Volume-I-Fundamentals-Edition-Ser...
Read the first 6 chapters very carefully and you will have rock solid foundation. Then skim through event handling, exceptions, streams and generic programming.
The older, third edition is also free[2].
[1] http://www.amazon.com/Thinking-Java-Edition-Bruce-Eckel/dp/0...
Honestly, how many programmers have actually read any book about programming outside of University classes? I'm guessing not many.
On another note, Effective C++ is not only a great book, it is the book which single-handedly made me a much better programmer, and made me understand C++. This is after half a year of training/working in C++. It is my most highly recommended book for really grokking C++. My only regret is that there isn't a similar book for most of the languages I know.
Obviously you care, and I care, and arguably most people reading HN care. But I believe that for a large percentage of programmers, programming is just their job. They do it, they get paid for it, and as long as they can keep getting paid for it, they don't need or care to "grow as a developer". It's just not a priority in their life, or even a goal.
While doing the exercises of course (just browsing the pages is not enough).
In contrast, Practical Common Lisp teaches you very little, however it showcases the power of the language very well, and therefore it's easier to sell.
Also, I've read the whole Code Complete and it was also interesting and I considered it one of the best books for programmers.
As for CLRS - boring as *%&^%#, I just can't manage to get past the sorting chapter. AFAIR there are not exercise answers so one is left alone when doing them, which mostly disqualifies every such book for anyone who is studying it on it's own, not in a class room.
Skiena's book is far, far better written, but unfortunately some of the exercises are to thought for me so when I'm reading my exercises are from 2-3 chapters behind. Although it's good that there is a wiki with (not always correct) answers.
Haven't read TAOCP.
http://www.amazon.com/Programming-Language-Pragmatics-Third-...
As a clear, well-written, thorough text on PL, I can't recommend it more strongly.
I read the second edition cover to cover, and it was worth all the time I spent on it.
That said, I've still used it for my research ... although I can often find other sources that say things better, CC2 has made a good starting point for ideas on how to present ideas about code.
I've read it cover-to-cover, twice -- the original edition, and the 2nd edition. Brilliant stuff.
Some books are references and some are read throughs. I read Code Complete while in college and thought it really helped my programming. Effective Java is another great book that I've read. The Pragmatic Programmer is another one that I've read that really is worth the time.
Many books are just good references though. Pick it up and read a chapter for example. I think the more experience a programmers gets the less they need to read right through a book. When looking at a book on a particular language I can usually skip the first half because I know the parts that are common across most languages. I only need to know what's different/cool/idiomatic in this particular language.
Algorithm books are another example that falls into mostly the reference category. I don't think I've read any entire algo book, but I have read many chapters from many different algo books that touched on what I needed to learn at the time.
Ironically, I didn't take the course that required it, and remain ignorant about compilers to this day.
I nominate Stepanov's Elements of Programming to the second list. Beautiful, dense, and a perpetual shelf ornament. Stepanov's papers, especially the one that launched the STL, Fundamentals of Generic Programming (with James Dehnert) is a masterpiece.
I have some favorites that show my age:
Software Tools by Kernighan and Plauger. Can be thought of as the poor-man's Dragon book.
The Practice Of Programming by Kernighan and Pike. As if the UNIX way needed any defending after almost 40 years.
Reliable Software Through Composite Design and Composite/Structured Design by Glenford Myers. You have to get past the ancient languages and flowcharts. These books describe modularity and module strength and coupling and are full of good ideas that still apply.
Database In Depth by C.J. Date, for programmers who haven't read Date's textbook on databases and probably don't need to. I do wish the NoSQL weenies would read Date's Introduction To Database Systems for some history and humility. Database technology has been there, done that, moved on.
Another commenter mentioned SICP, I'd add Let Over Lambda and On Lisp which while I haven't read cover to cover I've enjoyed every section I've read so far...
In the end I don't really agree with the author's conclusions that we shouldn't recommend books we haven't read at all. Passing on recommendations of others is defensible--after all, if someone asks for a recommendation they usually want one, not a response of "I don't know" or "Go do your own research!"
Perhaps the post should be rephrased to "However, unless you have at least a Masters degree in Computer Science (and in Algorithms specifically), I doubt you've HAD TO read more than a few selected chapters from Introduction to Algorithms."
While I have worked through a decent amount of CLRS myself, I think there are much better ways to learn how to solve algorithmic problems. For example, programming competition books like Programming Challenges[1] forces students to solve real-world-ish problems according to performance constraints - a time constraint, either artificial (e.g., problem statement requires execution within 2 seconds) or actual (e.g., choosing an algorithm that is too slow means the sun will burn out before the algorithm terminates).
Books and contests of this nature teach algorithmic thinking, which is far more important than the actual algorithms themselves. It also provides a context for implementing these algorithms, which means the student gets to see the more practical aspects as well: testing it on corner cases, fighting with the chosen implementation language, relying on compiler optimization, etc.
If the goal of the undergraduate program is to develop practitioners of computer science, or even graduates headed for academia, algorithmic thinking is essential. I don't think CLRS is necessarily the best way to teach that, and it certainly isn't the only way.
[1]: http://www.programming-challenges.com/pg.php?page=index
I understand that the title of the post is about books programmers recommend, but computer science extends far, far beyond programming and learning how to engineer solutions to real-world problems using algorithms.
The important parts to people doing research in algorithms are well-covered in CLRS, and that's part of why it's such an excellent book. It's full of rigorous proofs and a lot of theory, but that's because the point of the text is the design and analysis of algorithms themselves, rather than the application of them.
A university has an obligation to its undergraduate students majoring in computer science to teach them about computer science, and learning to think about designing algorithms, rather than merely learning about using them, is something that I would fully expect as an undergraduate majoring in computer science at any major university.
I suspect this is part of why more and more universities are offering degrees in Software Engineering, where the theoretical aspects of the field are not as important.
At UBC, we use CLRS for 2 undergrad courses: 3rd and 4th year Algorithm courses. I'm not sure what they use in grad level. Probably still covering CLRS.
That book is very thick and I have my own doubt a 3-month long semester can cover a lot from 1000 pages.
That was years ago, though, and I've heard anecdotally that now that there aren't 4x as many applicants to the program as there are spaces available, it's been made less rigorous.
I'm guessing people lie about the latter because:
a) they're much drier, and take more discipline to read
b) they indicate a more rigorous training.I was sitting in Steve's office when Lynn Takahashi, Steve's assistant, announced Knuth's arrival. Steve bounced out of his chair, bounded over to the door and extended a welcoming hand.
"It's a pleasure to meet you, Professor Knuth," Steve said. "I've read all of your books."
"You're full of shit," Knuth responded.
(http://www.folklore.org/StoryView.py?project=Macintosh&s...)
Seven Languages in Seven Weeks
The Elements of Computing Systems: Building a Modern Computer from First Principles
The Pragmatic Programmer
Programming Challenges
Statistics: A Gentle Introduction (not exactly a programming book, but statistics is good for everyone to know and this is book is easy to read and good at explaining the concepts)
I may also recommend SICP, CTM, The Art of Multiprocessor Programming, The Joy of Clojure, the OReilly book on Intel Threading Building Blocks, Reversing: Secrets of Reverse Engineering, Test Driven Development for Embedded C and others in certain situations but the above list is a general list I would recommend regardless of the persons proficiency level or programming interests.
That said, there's definitely a huge number of people who claim to have read Design Patterns, but actually have only read about Singletons and Factories in a Java book. It's a shame, because Design Patterns is one of the most formative books I've read as a programmer. Everyone should read it -- observing the way that patterns are (mis-)used in Java is a poor substitute for wrapping your head around the insights in GoF.
I have fond memories of the second half of the first volume. I've used the other two volumes as references. The fourth volume I bought, but haven't had time to read in any detail; I might never get to it.
Personally I liked Sedgewick's books on algorithms ("light and fluffy and readable") though I can't stand his coding style.
It makes the book a totally different and more complete experience.
So, this can be a book people read, but not really read. If this makes sense...
This is the equivalent to The C++ Programming Language. Written by Ken Arnold, James Gosling, etc.
Java: http://www.amazon.com/Java-Language-Specification-The-Editio...
What do you mean you can't find them?
Aside, in every programming job I've been in, there's been other programmers keen to lend me Terry Pratchett books.
The CLRS on the other hand I really recommend anyone interested in CS and programming purchase a copy of. It's not a book you read cover to cover, but get the first 1/3 well understood, and then when you have some downtime pick it up, scan the chapters, pick one the piques your interest and either learn a new algorithm or refresh on something you're getting fuzzy on.
To be fair I haven't spent any serious time with other recommended algorithms books, which I should. But every few months I find my self reading the CLRS and enjoying it.
The Dragon Book is however for people wanting to build parser combinators.
You can't parse context-free or context-sensitive languages with regular expressions. You probably mean that there are lexer generators that generate a lexer based on a regular expression specification, but you still need to provide a grammar to the parser generator if you don't write a parser by hand.
To be able to produce a grammar specification for the parser generator you need to understand formal grammars. To be able to produce an useful specification you really need to understand the general parsing algorithms and how the specific parser generator works.
All of this is vastly more involved than just understanding regular expressions. And this is just parsing, arguably the easiest part, not generating code or interpreting or all the other steps compilers might do.
Yacc is at least 33 years old, newer tools are better in some ways, for example Bison can generate a GLR parser, but they are just as easy (or hard) to use and require the same knowledge.
> The Dragon Book is however for people wanting to build parser combinators.
You probably meant parser generator, parser combinator is a different thing: http://en.wikipedia.org/wiki/Parser_combinator
You can't parse context-free or context-sensitive
languages with regular expressions
I didn't say that.Also, to add to your point, current regexp libraries have capabilities that far exceed the concept in the formal languages theory. Features like capturing buffers or look-ahead assertions cannot describe a finite-state machine.
Also, Perl has had support for recursive regular expressions. Perl 5.10 even has support for recursive capture buffers.
To be able to produce a grammar specification
for the parser generator you need to understand
formal grammars
IMHO, that's the same as saying that in order to be a programmer then you need to know lots of math, which is in general bullshit. Even before the formal theory was available, people have been building compilers the good-old fashioned way - by writing top-down LL(k) parsers, without necessarily having a name for this technique.But I also said that one should remember some basics from its theory of computation class, as it is helpful to know what a pushdown automaton is and the difference between it and a finite-state machine.
All of this is vastly more involved than just
anding regular expressions
It involves functions calling each other, sometimes recursively and loops and switches and remembering where you are in the text and doing repetitive transformations. It's as if you're doing real programming. You probably meant parser generator, parser combinator
is a different thing
No, I meant parser combinator.Then, I also think that your comment about people having written top-down recursive descent parsers for a long time without concrete historical reference is suprising, particularly when we all know of a prominent example (C) that you cannot parse with LL techniques (I rememeber a professor at university remarking on K&R probably not knowing about LL -- though I can't attest to this being true or not.)
I can also not figure out how you connect the Dragon book to Parser combinators. Having implemented parsers in both, monadic and combinatoric style (both of which btw. are a mess to debug) the best connection I can think of is translating formal grammar descriptions using parser combinators. Is this what you are referring to?
I like your characterization of compilers being just calling functions and loops plus switches and pointers to text. While we know about Church-Turing thesis, I am positive that the intricacies of database system implementation, operating system implementation and programming langauge implementation deserves distinction (which is supported by many of them having dedicated special interest groups.)
I also think that your comment about people having
written top-down recursive descent parsers for a long
time without concrete historical reference is
suprising
I do not have concrete knowledge or evidence about it, it was a statement based on intuition alone, sorry about that.The reason why I said it is because the first parser I ever wrote (something like 10 years ago), was a top-down LL(k) parser and I had absolutely no idea about what I was doing, but in the end it worked. Many programmers are choosing LL(k) implementations for their manually-built parsers because they are so easy to reason about and build manually.
I was under the impression that C can be described as LL(k). C++ definitely can't be.
About a compiler's implementation, I realize that it can get really messy, especially for statically typed languages and especially if you want to add type inference to it. Also agree on optimization. But the thing is, most people don't need to build turing-complete languages or need efficient translations to the target representation, they just need to parse DSLs or network protocols (hence my original comment).
This is NOT at all a knock on the book, since the title makes quite clear what it's about. But for whatever reason this one seems to end up on various "good to have on your shelf" lists when it probably isn't.
Eg. my professor owned NRC, and he did use it, especially the CD, to take algorithms as a plug-and-play starting point when doing some numerical analysis. Of course, you can also get similar algorithms off the web, but some professors are old-school like that.
The problem with Design Patterns is that much of the information in the book (but not enough of it) is accessible elsewhere.
Maybe now, but I don't think this was true when the GoF book was published in 1995. My recollection is that there weren't a lot of books on software architecture (code- or system-level) back then because it wasn't so much of an issue. Most of us were writing monolithic C code or trying to get reuse of C++ libraries. The whole "architecture astronaut" thing hadn't got started.
That is was so ahead of its time is what makes it an important book.
Programmers don't stand on each others' shoulders, but each others' feet.
I did actually read The C++ Programming Language when I was in high school.. at that time I thought it was a very important book. Now, with the insight, how dull it was and useless!
I have quite a few programming books, mostly cookbooks though, that show little examples/snippets and or O'Reilly reference books that I used to purchase when starting a new language to get an idea for the syntax. The best book that I have ever bought and read was "Advanced UNIX Programming" by Marc J. Rochkind. It helped me get a much firmer grasp on Unix programming and along with it C which I was lacking at the time.
I've got a copy of the Dragon book sitting on my desk, it is waiting to be read, waiting to be devoured and played with, but so far I just haven't had the time.
One book I would like to read and wrap my head around is the Gang of Four book, it seems like it is important to know the various different design patterns, but so far I don't feel like I have missed out and can recognise good design practices based solely on how they feel while I am writing them.
CLRS, TAOCP, and Gang of Four are all books I haven't read in their entirety, but have been indispensable for certain topics. I still recommend them to people all the time, and feel perfectly justified doing so.
In fact, very few do more than read selective chapters (which is OK).
I laughed when I read the article because I have checked out every one of the books he says programmers claim to have read (TAOCP, etc) from my company's internal library, and though I skimmed interesting parts (Go4, especially), I hardly read them.
Really? Because I still have mine from undergrad, and when I was using it to prep for a Google on-site, I was surprised that I had forgotten how far into it we had gone (there are dog ears back to chapter 36). Of course, that class was over ten years ago, and I (unfortunately) don't get to use it much these days, being that I mostly deal with RF and E&M.
It's highly digestible, covers many basic concepts (HTML, loops, control flow, variables, sessions, databases, oop), and has a number of good projects to walk through. While I've moved on to significantly more advanced topics (Python, functional programming), it took me a long way and laid a pretty solid foundation for the future. They actually went relatively deep in the details of how a website works.
BTW - I'd avoid ASP.Net for dummies. Relatively little code contained in that one...
I actually have read the GoF book, but I'm not sure that I'd recommend it to anyone.
To be more serious. All the books on the second list comes from people that were signinficant contributors to the field the book is about. That does not automatically make them good writers. All of the books on the second list is on the dryer end of the scale. I would recommend Appel's compiler book instead of the Dragon Book for example, even if it is less comprehensive. The Dragon book is written in an extremly confusing way (some oldtime compiler people have even described it as confused, esp in first edition).
TAOCP I generally recommend as a reference because I can only speak to its usefulness when used as a reference.
Edit: By "Other people" I do not mean "Other people who are doing graduate work" or "Other people who are in a senior level algorithms course." Really anyone who plans to do a significant amount of programming should read CLRS, even if he or she is still in high school.
I give an emphatic thumbs up to "Engineering a Compiler" (Cooper/Torczon) and also to the Appel books. They are fantastic, readable and digestable, and actually help get a compiler written.
And I will certainly read TAOCP once I have the money to reasonably justify spending it on the set.
I wouldn't really want to ever read a book on design patterns.
I wasn't reading for maximal knowledge retention (e.g. I would rarely do any of the exercises, though I would read them all and think about how I would solve them), but now I have a pretty good idea of what is in there and what isn't.
I found them a fairly easy read. It's just applied number theory :-)
I do not own volume 2, but poked around a bit in the sections with random number algorithms, as they have always fascinated me, since the time I wrote my own crude ones, in Pascal, back in the 1980s ;(
Really? I find that articles, blog posts and comments like to point out that this is something people actually say. I think that is untrue. It feels like one of the standard pseudo-oppositions that people take in order to write a piece - as if it was controversial - even if it isn't.
Obviously it's placed on greatest CS books list, or something that is valuable to have as a reference, but that's not the same thing as it being recommended reading for programmers.
The other books on the "have read" list are on my "don't bother reading" list. Code Complete, Pragmatic Programmer, Mythical Man Month et al aren't my kind of books. As far as design patterns go, I believe if you code in Python/Ruby/Perl etc, books covering them in Java/C++ are needlessly verbose and boring. I recommend Alex Martelli's talks
http://www.youtube.com/watch?v=0vJJlVBVTFg
http://www.youtube.com/watch?v=1Sbzmz1Nxvo
And this book which covers design patterns using Ruby.
http://www.amazon.com/Design-Patterns-Ruby-Russ-Olsen/dp/032...
Both approaches actually show you practical examples of design patterns in the standard library or real world problems, and shuns patterns which aren't applicable to the language or are too trivial. These talks aren't the end-all, but they will give you a good overall knowledge, and will make further exploration easy.
And from the "haven't read" list, CLRS is a good book and isn't as dense as it is generally taken to be. It does have sections on proofs, but you can skip it and jump directly to the data structure/algorithm. The pseudo code used in the book is extremely clear, and will convert to simple python in most of the cases. Use it as a reference, or read first few hundred pages. If the book isn't for you, you will know it after you have read the first 100 pages.
Another book I recommend is Sedgewick's book on Algorithms. I have read the C version. It mostly covers basic data structures and some accompanying algorithms. The code is succinct(sometimes needlessly so) and more importantly, it works. It doesn't sit well with everyone, but I liked it - it helps me see the whole picture without bombarding me with a lot of code.
Skiena is another obvious favorite.
Dragon book is decent, but you need guidance and discipline to make anything out of it. Consult your peers or teachers while using the book, or use another book.
I haven't read TAOCP and it's low on my list for now. I have read bits and pieces and I didn't find it as fascinating as I had hoped. It's dense and extensive, and can be used as reference.
"Effective C++" will be a better alternative to "The C++ programming language". But I must say, when I first read "The C++ programming language", I found it fascinating - lengthy, but fascinating. That would be mainly because I was beginning programming when I first read it.
Calling programs like that "pearls" just seemed too wrong to me to go on.
I know I'll learn more out of the book if I don't care of the small nitpicks like "gets()".