In this post I present some thoughts about the way people around me and myself learn new things. Specifically, how to go about learning new programming languages from the perspective of an experienced programmer.
The boring introduction
When I was learning to program computers for my own entertainment I did it because there where things I wanted to accomplish with the computer. It was fun to do it and I was eager to learn how to do it and experiment with it, but in order to learn I always tried to do something “real”. Later on in school I took a subject on computer programming and there I learned a new language (Pascal was the language of choice at the time) and, of course, I had assignments to do. Now both my own goals and the assignments where very helpful because they made me focus on experimenting with the language rather than scatter my thought about what to do with it.
Especially at school, the method I was taught with was one which fit me very well: the teacher would dictate a section of the text-book to us (we didn’t actually own the text-books, the only material we had was the dictations he gave us). Then he would go over that section again, maybe on the next class, and explain things in detail, give examples, and so on. I had a notebook which I kept thoroughly organized, with the theory the teacher dictated and then examples, tips and tricks, notations on the side of it, next to the relevant bits, the works.
Then there where the class assignments, which where very helpful because, not only where they aimed towards being best accomplished with the parts we had just learned about, but they provided laser-sharp focus for thought. The fact of the matter is that I was lucky. While most kids where getting to grips with the notion of algorithmic solutions and language constructs I already had some notions of all that and I could take each assignment as a personal challenge: I had to find the best way to do it for whatever measure of “goodness” I chose. The “Best Way” could be the fastest, or it could be the one with less lines of code, or even the more “elegant” way. This last concept of “code elegance” actually caused not a few frowns from my colleagues who considered themselves lucky to have hammered together an answer in as little time as possible and then got on with playing ball or talking about clothes and hair… :-)
But anyway, I got to experiment with the language, a bit at a time, adding more bits as I learned them and experimenting with multiple solutions for a given problem, learning the best way to solve each issue and combine solutions in the process. I had all the time in the world to learn it and it counted as homework, not “fun and games” time. What a bonus!
Fast forward to this day, many years later, after having gone through a computer science course in university and a number of years on the field, not actually as a full-blown programmer, but mainly as a systems architect which also does quite a bit of programming.
Things are a bit different today. There are, of course, new languages springing up every so often and some of them are actually quite appealing. Now after a respectable number of years on the field I am much more able to grok a language by skimming through some discussions and explanations of it and talking with people who use it. Algorithms are the same in every language, data structures are more or less equivalent across them (yes, I know I’m generalizing like crazy, but if you take a high-enough view of things it tends to look like this) and in the end, taking into account the big “classes” of languages and their fundamental differences (which I won’t go into here) you are left with the choice of the best language for each specific task you want to tackle. Some make it easier to work with a given data structure you wish to use by providing better modeling for it, others provide the control structures you need to use and so on, but in the end, if you put enough effort into it you can solve most problems with almost any language you care to use.
How do you make a choice then? Well, it isn’t enough to just read the blurb, talk to some programmers and see a few “hello world” examples, you really have to know the language you are contemplating in order to ascertain if it is indeed better than the other ones. (Almost) all of them can do it, but one may be better. The problem is that being better is probably in the details so you really have to know your languages.
And then, of course, some people like to learn new languages just for the fun and challenge of it. Nothing wrong there, I find it very entertaining actually.
The problem then becomes how you can go about learning new languages, with the limited time you have at your disposal, and with the tools you already have installed in your brain.
I found that myself, and people I know, usually take one of the following approaches:
By the book
This method assumes you can actually read through a book on a new language and probably without writing a line of code (remember the time constrain), be able to get all the relevant information into your brain. I couldn’t do this when I was younger and I certainly cannot do it now, if I don’t experiment with it somewhat it just doesn’t stick.
On the other hand, assuming you get a good book, this way you get the most important facts and techniques on the new language and you can map your mental tools, best known algorithms, tricks and so on onto the new language and also get a structured and correct insight into the right way to do things with it.
You’ll end up using the language more efficiently and making things work with the least effort.
Just do it
Other people, like Rui Carmo take the “tackle a real project with it and enlightenment will come your way” approach.
The typical hands-on approach, where you sit down with a task or assignment, some tutorials, examples and/or cookbooks for the specific language and just start trying to write the code you want in it.
Things you learn this way tend to stick better in your brain (in my case at least) and the difficulties you encounter trying to map your mental tools into the language and the way you solve those problems will give you a good insight into the language’s capabilities. Of course I’m talking about a non-trivial and especially interesting assignment. For all the tradition they carry around, “Hello Worlds!” are rather useless as a learning experience in any language you care to think of.
On the other hand, this way you may (and usually do) and up trying to coax your way of doing things into a language which may have other, more efficient ways of doing them. It is not that rarely that I find a piece of code on a language I know very well, which is behaving or performing badly. Upon examination of the code, I can immediately tell which language the programmer that wrote it used to work on. After that it is usually a matter of minutes the re-writing of the offending piece of code to make it work better/faster/whatever. Clearly the programmer might have been a good programmer on the other language and even a good programmer “per-se”, but not knowing the language in enough depth made his code sub-optimal, even if it did work.
The rhyme and the reason
So properly learning a new language is rather important if you’re ever going to use it, but learning it properly takes time and effort and not everyone can afford to spend that time. What is the best way to do it then?
Personally I like the book approach a lot, because someone who already knows the programming concepts can get the right idea about their implementation on the specific language and can then be more effective when writing code in it. You just do things right the first time instead of battling with the language to make it do what you want in what can turn out to be the wrong way to go about it in that specific language.
But then, given the shortage of time people (and me in particular) have to devote to these things, spending the time reading about rather than doing it is rather painful and, of course, geeks love to play with things hands-on don’t they? I mean, learning what was inside the radio was interesting, but not half as interesting as actually opening it up and seeing for yourself. Even if there where some pieces left over after re-assembling it… :-)
Gone are the days when I was a good boy for working so hard on my homework assignments and was spoon-fed with the language facts at school, while left with enough time to play around with it afterwards, so I guess the mixed approach is the way to go now: find a good introductory book on the new language, find out the interesting chapters in it and read them with care (typically a good introductory book will explain how you work with general structures and how you implement some basic algorithms you already know, while giving some light insight into the inner workings of the language and why this way of doing things works best). Then choose a project (your assignment) and go for it using the new language. If you can get a “cook book” for the language it is really helpful because you will then learn about different ways of solving each problem you have to solve and why one way is better than the other for a given situation (assuming, once again a good “cook-book”).
This way you get the benefit of the “lecture” from the text-book and follow it with some useful hands-on experience. And the key here is useful, because if you just try and follow the introductory book’s assignments you end up ditching them because of lack of time and never actually get around to using the language properly and getting to know it better.
Anyone has some thoughts or tips on this topic?
Note: This has been sitting in my laptop waiting to be finished for quite some time now. Fortunately I was able to find the time during my vacation to write some more, but I still think the overall post is a bit confusing. But then, I don’t want it to just sit here and rot so I’ll just post it and get it over with. Hey, I’m on vacation, just relax! ;-)
Technorati Tags: Programming