Sunday, December 14, 2008

Freely Available Programming Books

In an earlier post, I listed some frequently recommended computer programming books. I got some good feedback from that post, so I thought I'd go a step further and provide some links to programming books that I've found for free online.

Please note that I'm going against my own previous advice here, as I haven't finished reading every one of these books from cover to cover (I haven't even started SICP, I admit), so don't take these as endorsements from someone who has read the books.

NOTE: One Anonymous poster pointed out that there's more material missing from the Google Book Search selections than at first appeared. I've had to remove those books, but you can search their selection through the link provided.

Without further ado, I present to you the 7 best free programming books that I could find online. Enjoy.
  1. Structure and Interpretation of Computer Programs
  2. Thinking in Java (3rd ed.)
  3. Thinking in C++ (2nd ed.)
  4. Algorithms and Complexity
  5. How to Think Like a Computer Scientist(Learning with C++)
  6. Programming Ruby (1st ed.)
  7. Dive Into Python
Please let me know if you find any of these links useful. I'm particularly interested to learn what people think of SICP, since it's been on my "to read" queue for quite awhile. If you decide to read it, be sure to check out the SICP companion video lectures. (Update: I've started reading SICP since this was first published, and I'm keeping track of my progress starting with The SICP Challenge.)

I'd also certainly be interested to learn of any other free online book resources that anyone can recommend.

Related posts:

Even More Free Programming Books

Wednesday, December 10, 2008

Books Programmers Don't Really Read

Mark Twain once said that a classic novel is one that many people want to have read, but few want to take the time to actually read. The same could be said of "classic" programming books.

Periodically over on Stack Overflow (and in many other programming forums) the question comes up about what books are good for programmers to read. The question has been asked and answered several times, in several different ways. The same group of books always seems to rise to the top, so it's worth it to take a look at these books to see what everyone is talking about.

Books Most Programmers Have Actually Read
  1. Code Complete
  2. The Pragmatic Programmer
  3. C Programming Language (2nd Edition)
  4. Refactoring: Improving the Design of Existing Code
  5. The Mythical Man-Month
  6. Code: The Hidden Language of Computer Hardware and Software
  7. Head First Design Patterns
  8. Programming Pearls
  9. Effective Java (2nd Edition)
    or Effective C++
  10. Test Driven Development: By Example
I've read all of these books myself, so I have no difficulty believing that many moderately competent programmers have read them as well. If you're interested enough in programming that you're reading this blog, you've probably read most, if not all of the books in this list, so I won't spend time reviewing each one individually. I'll just say that each of the books on the list is an exceptional book on its respective topic. There's a good reason that many software developers who are interested in improving their skills read these books.

Among the most commonly recommended programming books there is another group that deserves special consideration. I call the next list "Books Programmers Claim to Have Read". This isn't to say that no one who recommends these books has actually read them. I just have reason to suspect that a lot more people claim to have read the following books than have actually read them. Here's the list.

Books Programmers Claim to Have Read
  1. Introduction to Algorithms (CLRS)
    This book may have the most misleading title of any programming book ever published. It's widely used at many universities, usually in graduate level algorithms courses. As a result, any programmer who has taken an algorithms course at university probably owns a copy of CLRS. However, unless you have at least a Masters degree in Computer Science (and in Algorithms specifically), I doubt you've read more than a few selected chapters from Introduction to Algorithms.

    The title is misleading because the word "Introduction" leads one to believe that the book is a good choice for beginning programmers. It isn't. The book is as comprehensive a guide to algorithms as you are likely to find anywhere. Please stop recommending it to beginners.

  2. Compilers: Principles, Techniques, and Tools (the Dragon Book).
    The Dragon Book covers everything you need to know to write a compiler. It covers lexical analysis, syntax analysis, type checking, code optimization, and many other advanced topics. Please stop recommending it to beginning programers who need to parse a simple string that contains a mathematical formula, or HTML. Unless you actually need to implement a working compiler (or interpreter), you probably don't need to bring the entire force of the Dragon to bear. Recommending it to someone who has a simple text parsing problem proves you haven't read it.

  3. The Art of Computer Programming (TAOCP)
    I often hear TAOCP described as the series of programming books "that every programmer should read." I think this is simply untrue. Before I'm burned at the stake for blasphemy, allow me to explain. TAOCP was not written to be read from cover to cover. It's a reference set. It looks impressive (it is impressive) sitting on your shelf, but it would take several years to read it through with any kind of retention rate at all.

    That's not to say that it's not worthwhile to have a copy of TAOCP handy as a reference. I've used my set several times when I was stuck and couldn't find help anywhere else. But TAOCP is always my reference of last resort. It's very dense and academic, and the examples are all in assembly language. On the positive side, if you're looking for the solution to a problem in TAOCP (and the appropriate volume has been published) and you can't find it, the solution probably doesn't exist. It's extremely comprehensive over the topic areas that it covers.

  4. Design Patterns: Elements of Reusable Object-Oriented Software (Gang of Four)
    Design Patterns is the only book on this list I've personally read from cover to cover, and as a result I had a hard time deciding which list it belongs on. It's on this list not because I think that few people have read this book. Many have read it, it's just that a lot more people claim to have read it than have actually read it.

    The problem with Design Patterns is that much of the information in the book (but not enough of it) is accessible elsewhere. That makes it easy for beginners to read about a few patterns on Wikipedia, then claim in a job interview that they've read the book. This is why Singleton is the new global variable. If more people took the time to read the original Gang of Four, you'd see fewer people trying to cram 17 patterns into a logging framework. The very best part of the GoF book is the section in each chapter that explains when it is appropriate to use a pattern. This wisdom is sadly missing from many of the other sources of design pattern lore.

  5. The C++ Programming Language
    This book is more of a language reference than a programming guide. There's certainly plenty of evidence that someone has read this book, since otherwise we wouldn't have so many C++ compilers to choose from.

    Beginning programmers (or even experts in other languages) who want to learn C++, though, should not be directed to The C++ Programming Language. Tell them to read C++ Primer instead.
As I said before, I know there are a few of you who have actually read these books. This post isn't intended for you, it's intended for the multitudes who are trying to appear smarter by pretending to have read them. Please stop recommending books to others that you haven't read yourself. It's counter productive, as often there is a better book (more focused on a specific problem domain, easier to understand, geared more toward a specific programming language or programming skill level) that someone more knowledgeable could recommend. Besides that, you may end up embarrassing yourself when someone who has actually read TAOCP decides to give you a MMIX pop quiz (if you don't know what I'm talking about, then this means you).

Friday, December 5, 2008

Pair Programming

I had the chance to do some pair programming this week and I thought I'd share my impressions. For those of you who may have just recovered from a recent coma, pair programming is a technique where two programmers collaborate on a piece of code using one keyboard and monitor. The person typing is called the driver, and the person observing is called the navigator.

I entered in to my pair programming arrangement as not exactly skeptical, but I wouldn't say I was convinced by all I had read. I'd need to spend some more time coding with a partner (or see some citations) before I'm prepared to accept everything the Pair Evangelicals claim. Regardless, I was just curious enough to give it a chance and see if it could work.

The thing that I noticed within the first hour was that having a navigator was much less of a distraction than I had feared. I was worried that it would devolve into an unproductive chat session, but that didn't happen. There was a bit of chit-chat now and then, but each time within a few minutes one of us would remind the other of the mountain of work we had to do. Having a partner wasn't a distraction at all, it actually kept me slightly more focused than normal.

Another thing that struck me fairly quickly was that having a second pair of eyes on my code while I was writing it kept me honest. I took fewer shortcuts, commented my code properly, tested more, and refactored more often. All of the things you're supposed to do even when no one is watching. It was like having a code review really early in the project.

When it was my turn to navigate I noticed something else. I think differently when I'm not the one typing in the code. Having my hands on the keyboard forces me into a very logical mode of thought where I'm worried about details. Observing someone else writing code allowed me to think at a higher level of abstraction. You may have experienced this yourself when you're designing on paper, at a whiteboard, or writing pseudocode. Not worrying about the details of what will make your code compile allows you to think more about design-level aspects of your software.

Overall I would rate my experience with pair programming as a success, but I don't think that it's strictly necessary. If you haven't tried it, I would recommend it for a few days just to see what it's like. It has been worth it for me just to note the difference in my own way of thinking when I'm away from the keyboard. This difference will likely cause me to take more frequent breaks from typing so I can spend time at the whiteboard thinking about my software from a different point of view, even when I'm coding solo.

Friday, November 28, 2008

On Learning

I've been reading Pragmatic Thinking and Learning by Andy Hunt (who co-wrote the The Pragmatic Programmer) lately. The book brings up idea of second-order incompetence, which means that a novice at a particular skill is so unskilled that they don't even realize how unskilled they really are. This leads beginners to greatly overestimate their own ability. In many cases, it can lead a beginner to be more confident in their own skill than an expert.

The second-order incompetence theory applies to any skill in general, but I've noticed that it applies extremely well to programmers and their particular set of skills.


I've heard some programmers say that it takes anywhere from three days to three months to learn a new programming language. I personally feel that this is an extremely low estimate (I've been learning C++ for several years). Three days is barely enough time to learn the syntax of a new language. Three months is likely enough time to learn the syntax and a few common libraries of a language, but it isn't really enough time to get you beyond the "Advanced Beginner" skill level. It's probably just enough time to give you the confidence you need to be extremely dangerous.

The book goes on to explain that it really takes more on the order of ten years to truly master any non-trivial skill, whether it be playing chess, playing music, or flying an airplane. Peter Norvig quotes some of the same research when he advocates the ten year time scale for programmers in his article Teach Yourself Programming in Ten Years.

These ideas are hardly new. Socrates was onto a similar idea almost 2500 years ago when he said

"True knowledge exists in knowing that you know nothing."

In programming, as in almost any worthwile pursuit, this means that you have to give yourself time to reach a skill level high enough that you know how much you don't know. If you catch yourself feeling confident in a given language after only three days (or even three months), try to realize that you've probably only seen a tiny fraction of the what there is to see. Remember that 90% of an iceberg is below the surface.

Tuesday, November 18, 2008

Friday, November 7, 2008

NetBeans PMD plugin

I was installing NetBeans on a new computer recently (and prompted by a question on StackOverflow), so it came to my attention that, due to the blazing fast speed of NetBeans development, the instructions for installing the NetBeans PMD plugin are a little outdated. Here's an updated set of instructions*.

1. Download the latest PMD release from SourceForge.
2. Unzip the zip file to any directory. I put mine in C:\Program Files\Java\pmd-netbeans60-2.2.1, right next to my JDK directory. You'll see that the zip file contained a .nbm file that encapsulates the plugin.
3. Run NetBeans and click Tools -> Plugins
4. Go to the Downloaded tab on the Plugins dialog.
5. Click on the Add Plugins... button at the top of the tab.
6. Navigate to the directory where you unzipped the PMD plugin zip file.
7. Select the file named pmd.nbm.
8. Click the Open button.

You'll get a dialog saying that the plugin isn't signed, asking you whether you want to accept it anyway or cancel the installation. You'll need to accept it without a signature in order to use the plugin. You'll need to restart NetBeans after installation is complete.

You can run PMD by selecting a single source code file or an entire source package, then selecting Tools -> Run PMD (or Ctrl-Alt-P) from the main NetBeans menu.

To change from the default rule set go to Tools -> Options on the main NetBeans menu. On the Options dialog, select the Miscellaneous toolbar button, then the PMD tab. On the PMD tab you can press the Manage Rules... button to change the default ruleset, or press the Manage Rulesets... button to create a custom ruleset of your own.

*Note: I'm doing the installation for NetBeans 6.1 running on Windows XP as I write these instructions. I've verified these instructions using NetBeans 6.0.1 on Ubuntu.

Saturday, October 4, 2008

Sometimes you're still wrong...

It seems funny how sometimes you can just know you're right, and still be proven wrong. Take for example this old programming idiom.

if(condition == true) {
return true;
}
else {
return false;
}

Everyone should recognize this by the time they've completed a CS (or equivalent) degree. There are two things wrong with the above code. First, if the condition variable is boolean, then there's no need to compare it to true. Second, the whole idiom simplifies down to just

    return condition;

There, we've just saved five lines. I've corrected this so many times I've lost count. Then what's my point, you ask? When is the six line version really okay? When you're debugging. Sometimes you want to set a break point where the condition is either true or false. If you only have the return statement to set the break point on, the debugger stops every time it hits that one line. That's really annoying if the condition you're interested in only happens once in a thousand evaluations.

So what's the real lesson here? Even when you know you're right, even when you've been right for years, you can still be wrong.