The Top 9½ Books In a Hacker's Bookshelf
grok-code.com
grok-code.com
Structure and Interpretation of Computer Programs (SICP), Abelson & Sussman
The Little Schemer, Friedman
The C Programming Language (K&R), Kernighan & Ritchie
The Analysis of Algorithms, Purdom & Brown
The Elements of Statistical Learning, Hastie, Tibshirani, Friedman
Biological Sequence Analysis, Durbin et al.
Artificial Intelligence: A Modern Approach, Russell & Norvig
Introduction to the Theory of Computation, Sipser
Introduction to Linear Algebra, Strang
GEB is my 1/2
1-4: Books on computer organization, operating systems, networks and distributed systems (I like the ones by Tanenbaum, but there are many).
5: Another about compilers/languages (the dragon book is a classic, but there are many others).
6: Something about Lispy-languages (e.g. SICP, but the Little/Seasoned Schemer is another favorite).
7: A book about algorithms. I have Knuth, but something less thorough covering a wider area may be preferable.
8: A book about the practice of programming. My favorite is The Pragmatic Programmer.
9: A book about software engineering as a profession (I recommend Peopleware.)
Curling up with a big fat book and reading about whitespace for 45 minutes isn't very rewarding in my opinion.
Just glancing at it occasionally will have you dropping your jaw at code you wrote in a hurry 6 months ago.
1. Advanced Programming in the UNIX environment
2. TCP/IP Illustrated
Both written by Richard Stevens.
What is an "Iterator"? It's an object that contains functionality to retrieve objects from a container. Period. The end.
Now, what is an "Iterator Pattern"? (Again, I don't have the book, so...) I think it is about 10-15 pages of how to define, describe, document, specify, graph, implement, re-use, contextualize and otherwise belabour the Iterator object.
But, at the end of the day, an "Iterator" is simply the next-next-next functionality moved from the linked list to another place. That's all it ever is, in practice. The book makes things worse by using PhD-dissertation levels of vocabulary and grammatical structures to describe simple, simple concepts. This gives confusion to people who don't see through the bull, and when they say "Aha! I understand Iterators!", they believe they've unriddled a mystery, and so become "educators" and "advocates" on behalf of others.
I speak from experience, and have no statistics on this.
One point it unfortunately doesn't cover is the large percentage of Go4 patterns that are just plain bad ideas. Singleton, for example, should just never be used: it's like relying too much on global variables, but worse.
The problem is people often use the Design Patterns book as a design manual but that's not what it really is - it's an attempt to catagorize ideas. The very fact that you used the term Singleton means that now you and I can argue the merits of using that pattern in different situations. Would you rather us attempt to do that without common terminology?
By the same token, there's nothing wrong with knowing what a goto statement is. But I'm glad we don't have a popular book that implicitly advocates its use, or college classes that teach it to students as if it's the state of the art in control flow.
However, I think there are completely valid uses of the "Singleton" concept. It can be an elegant solution to a lot of problems.
What I find offensive about Singleton is the idea that that the author knows there is no context in which you might want more than one of some object. This is especially bad in libraries, where having objects enforce their own uniqueness breaks the ability for me to use two FooManagers where the author only envisioned using one. Designs are generally improved by accounting for the possibility of more than one instance, even if it isn't immediately necessary.
How is a global variable different from a singleton, anyway? Seems to me, in distributed and multithreaded environments the singleton problem is still a hard problem.
A global variable is different from a Singleton because if you write a Singleton class in some module that I want to use, I have to fork your module if I want to make it possible to use two of them. If you use a global variable, I can always make a second global variable.
This maybe isn't quite "Singleton", but it is at least a useful case for limiting the number of allowed values of a class.
The analogies to alcohol are disturbing.
Near as I can tell, design patterns are just ways of vaguely describing common solutions to common problems. They say, "You might try to solve problem X in some language by creating an object that does Y."
In lieu of actually understanding the specific problem they're facing, the inexperienced or less skilled programmer then looks through their dictionary of design patterns, finds something that sounds like it fits, and then proceeds to throw some very generic code at their problem until it goes away.
This strikes me as very similar to the problem Feynman discussed in "Surely You're Joking", when he worked as a professor in Brazil and came to realize that, on a national basis, the students had all been taught to memorize entire books of facts, but hadn't done experiments and didn't understand the concepts behind the things they were taught.
I agree with you, actually. My point wasn't that the design patterns themselves are wrong, or necessarily bad, it was that (I think) they'll tend to get used in situations where the programmer doesn't understand the immediate problem or solution well enough to deal with it directly.
Anecdotally, this came up somewhat recently when the question of whether or not it's "OK" to return early from a function got briefly passed around the net. I noticed a lot of instances where people were coming up with some pretty absurd reasoning to justify always doing it one particular way, the 'textbook' way if you will.
Myself, I think it's _sometimes_ OK to return early from a function. It depends on what you're doing. You have to understand the situation you're looking at, and all of the various circumstances around it.
So, the idea of "never return early from a function" isn't necessarily wrong, but it does indicate that the programmer probably doesn't really understand what they're doing.
Most patterns in the book are not that trivial, so I don't think you can apply them without understanding them (in general).
Using design patterns really helped me in a large project I did in C# two years ago - although I must admit I used the friendlier Head First Design Patterns as my reference rather than the original Design Patterns book.
I honestly think I would not have been able to do the project without the aid of design patterns. The project's architect was living too high in the clouds to grasp why his architectures were unimplementable, yet tried to micromanage the implementation as well. He continually specified implementation details which violated basic constraints of the language syntax and the static type system (like asking for multiple inheritance in C#). So I would use design patterns to get around a language limitation to do something close to what he wanted. Since he didn't understand design patterns, he found my explanation of how the design pattern accomplished the trick impenetrable enough to just leave it alone.
It backfired on me when he learned the Singleton pattern (which he kept mistakenly referring to as the "Simpleton" pattern), and started insisting that every object should be a "Simpleton".
Anyhow so the reason I didn't downmod you, is that I do think design patterns are useful, but they fix a problem which is partly that the language is broken, and partly a people problem.
I'm also reading "Programming Collective Intelligence" right now which is pretty awesome so far!