How to learn a new language

Throughout my software development career, I've tried to be open to the prospect of learning new programming languages--not just to accomplish a job or pad my resume, but for my own edification and consciousness-expansion. While I haven't learned as many as I would like, I have picked up a few; most recently, I've been endeavouring to learn Haskell.

For the uninitiated, Haskell is a pure functional language with lazy evaluation. These two key features of Haskell make it almost completely unlike any imperative language I've used. In C++, Java, Python, PHP or Ruby, you typically build a program with sequential statements that change the values of variables; when the program executes, the state of these variables mutate until you eventually get the output or result you're looking for. Haskell doesn't work like this at all--its variables don't vary, and sequential execution of statements is almost unheard-of. There are no loops, and no side-effects. The alien nature of Haskell is one of the reasons I was drawn to it, and I have found that learning it (even just a little bit of it) has extended and deepened my understanding of programming in general.

But how does one go about learning a new language? In this case, I started with some of the many tutorials, drawing as much knowledge and experience as I could from each one. Nearly any semi-popular language is bound to have many different online resources, varying in length and detail from the short introduction to the full-blown textbook. With a little searching, you can probably find more reading material than you know what to do with, on just about any language you might be interested in learning.

Reading books and following their exercises can only go so far, though. I found that I didn't really begin internalizing Haskell until I set myself loose on some programming exercises. You can't get better at any skill unless you practice it, and this is especially true of programming. I suppose it's possible to make up my own practice exercises, but I found it more effective to attempt some well-established exercises designed by others. 10 Puzzle Websites has some good references; one of the most famous, and also one of my favorites, is Project Euler, which has hundreds of mathematical and logic problems. Most of them require some programming to solve, and beginning with the simplest problems is a great way to begin truly applying the language you're learning. Another good site is Programming Praxis, though the problems there are typically more complex; you may want to wait until after tackling a few of the Project Euler problems before moving on to those.

Ultimately, I think the only way to fully absorb a language is to write real software using it; to build a tool from scratch, then use and maintain that tool over a period of time, or to participate in development of an existing program in that language. I haven't quite gotten there yet with Haskell; the closest I've come is occasionally modifying the configuration of my favorite window manager XMonad (written and configured entirely in Haskell), so I am still looking for a project where I might make better use of what I've learned. I know that when I was first learning Python, I didn't feel very competent until I was building actual, useful software with it.

I hope to learn more programming languages some day. I've dipped my toes into Lisp and some of its dialects such as Scheme, but I would love to learn more. It would also be nice to get some C# exposure, and I've heard some good things about Erlang. On the other hand, I don't want to spread myself too thin; I know from my experiences years ago with C++ and Perl that if I don't stick with a language and use it frequently, it's likely to slip into the dark corners of my mind, where I can no longer say with any confidence that I still "know" it.

In the end, I believe practice is everything. A runner who doesn't run is no longer a runner, and a Haskell programmer who never programs in Haskell is not really a Haskell programmer. If I want to become a Haskell programmer, I need to keep practicing.