I often hear the same question at conferences--what books should I read to be successful?  Technology books have been massive and plentiful from the days of Knuth's Art of Computer Programming to today's mega-pulp series like [Programming Language] Unleashed and [Operating System] Secrets Revealed. It's impossible for one person to keep current on everything, which is why I so frequently am asked "what is it that I really need to know?"


My answer hasn't changed (much) since the first time I was asked. I don't believe it's important to know a lot of technologies because they change all too quickly. What's important is to understand how these technologies work. If you can reason critically about a new technology you can easily pick up new skills when you need to.


Some technologies don't change, of course. For example, computer architecture has been much the same my entire life. Learning C++ will no doubt be worth your while. Being able to program against the Win32 API seems pretty useful. If you could predict which of the new technologies will succeed then you could just learn those. But if you can predict accurately which technologies will succeed you should forget programming and turn your talents toward stock speculation!


COBOL did so well that for years it seemed like it would rule the world. (In fact, it's still popular in some markets as Fujitsu's COBOL .NET.) Nowadays, knowing COBOL won't help you get many jobs. FORTRAN was the only programming language to know from the very beginning but times have turned against it. And these two languages had pretty good runs. I bet you can name at least five web programming technologies, two of which are obsolete. What can you learn today that will still be useful tomorrow? I recommend learning the basics. Stretching your mind. And applying what you already know to creating something useful and interesting.


Where do you learn the basics? Experience, of course. But even if you don't have much of your own, you can borrow some of Jon Bentley's. He's the author of one of the greatest books about programming ever written, called Programming Pearls. (Don't confuse it with Larry Wall's Programming Perl which is also a great book but definitely not in the same class as Bentley's book.) Bentley's book is a collection of about 20 problems which he analyzes and solves with elegant and insightful reasoning. It's a fun book to read and it's fairly short. And it's been around long enough that you can probably find it in your own language or in a used bookstore. (If you happen to find a copy of Programming Pearls Volume 2 let me know--it's been out of print for decades!)


How do you stretch your mind?  Computing was for years a very theoretical pursuit. In days of old when machines were scarce, they developed three main models of computation: Turing machines, Backaus Normal Form, and lambda calculus. While all these models have the same expressiveness, almost all popular programming languages follow the Turing machine model. Backaus Normal Form is used to create parsers, and lambda calculus forms the basis of functional popular languages. Stretch your mind a little: learn a little about lambda calculus by learning a functional programming language.


At one time I did a lot of programming in Lisp, which was a very popular language back when academic types ruled the computing world. I don’t use it at all today, but learning it certainly wasn't a waste of time because it changed the way I think about programming. In fact, when I first started at Microsoft I still used to prototype my algorithms in Lisp to prove them quickly, then I would convert them to C++. (That stopped when I learned Perl…)


All functional programming languages are pretty much the same. (The previous statement is similar to saying "C# is pretty much the same as C++.") There are some proud outliers--Haskell is the purest of the functional languages, and Scheme has a reputation for being simple and useful. But they're all different flavors of the same paradigm. (In fact, you could probably learn a fair bit about functional languages by limiting yourself to the weird new features of C# 3.0, but working in a "real" functional language will help to keep you honest.)


I'd suggest learning F#, which is developed at Microsoft Research. It comes from ML, which is a reasonably good family of functional languages. One ML variety is OCAML, which extends ML with the ability to use objects. F# is a dialect of OCAML and allows access to the whole .NET Framework. It also has fantastic Visual Studio integration which means you get autocompletion, Intellisense and a world-class debugger. I don't know if Microsoft shipping a functional language means they will finally come back to rule the world. But I do know that Visual Studio is far more pleasant than Emacs, my editor of choice when I was using Lisp heavily. F# info is available at http://research.microsoft.com/fsharp/fsharp.aspx.


Lastly, do something useful with what you already know (or what you almost know.) My bookcases  at work are overflowing with books. I have too often falling victim to reading about something and thinking I've learned it well enough. But without applying the knowledge you miss out on the best part: the satisfaction of building a program that does something, no matter how simple. Maybe you find computing Fibonacci or reversing strings a good way to fritter away an afternoon, but I like to interact with the world. I do that by developing little tools that help me with my work. Some people like to program games; others like to write programs to solve puzzles. Just write something that you find interesting and useful that you can show off to your friends.


I've attached a little program I wrote years ago. I had just bought my first laptop and it wasn't very powerful. I found Windows Media Player to be a bit heavyweight for my poor little machine and so I started looking for the smallest CD player I could find. Eventually I decided to just write one.


Writing a CD player sounds ambitious (well, it sounded ambitious to me before I started) but it turned out to be pretty easy to get exactly what I want. The CD player has no UI. In fact, my CD player doesn't even run while you listen to music. It just starts the disc spinning and exits. I let the Windows Multimedia Services take care of all the hard work for me. In the end, the most challenging part about the program was getting it to be small enough. And it is small enough: small enough that if you run it with the -c switch it will open a message box displaying all of its source code. Making the code fit into a MessageBox was the most fun part of the problem.


What's important is that I used my skills to fill a need. I learned a thing or two in the process. Writing a little tool that you'll use every day is a great way to remind yourself why you started programming in the first place. Understanding how to reason critically about problems will help you identify how and when you should use a given technology to solve that problem. And learning a functional language just might help to get you out of a rut one day when you can't think past the mindset you're stuck in.


So there you have it--my very biased opinion of what you need to know. More to the point, it's my opinion of what you don't need to know. If you find Silverlight interesting or you think it's the right tool to solve your problem by all means learn about XAML and .NET and go have fun. If you think knowing Flash will help you solve problems effectively then go learn Flex. But don't learn something just because you think everyone else must know it or that you might need to know it one day. Spend your time learning the basics, stretching your mind, and solving problems that you find interesting and fun.