Are you quite sure that all those bells and whistles, all those wonderful facilities of your so called powerful programming languages, belong to the solution set rather than the problem set?
-- Edsger Dijkstra
Introduction
I think the pragmatic programmer advices you to learn one new programming language each year. While this sounds perhaps plausible, I think this can be unattainable for the average non genius depending upon what you define learning as. Much like chess, programming languages are complex yet deceptively simple. You can teach the rules of chess to a novice in matter of minutes. Indeed within the hour a complete novice could be playing games on his/her own. Of course the games will usually end in disaster (and perhaps tears depending on age of the player). To learn the syntax of a new language is pretty easy. With reasonably good memory you could probably do this within a day for a simple enough language (i.e. not C++). If we call this learning the language, then sure we can follow the initial advice, but what would the point be? That would be aching to just memorize a new table each year to stretch your memory muscles.
If we need to actually learn how to use the language and be reasonably proficient in it, I don't think one language a year is a reasonable pace for us normal humans.
Language Categories
Learning different languages is still important though. I think another rule would be useful for programmers though,
What do I mean by category? Well, there are of course the big divide, imperative and functional languages. Since C++ is an imperative language, I'll assume that you already know that one. Functional languages are the ones that CS graduates usually dabble a little with in college. LISP, Haskell and ML are examples of functional languages.
In addition to those divides I would like to add assembly language and script languages to the list. I would encourage programmers to learn at least one assembly language. Today for games programmers it would be useful to read PowerPC assembly since it so happens that all modern consoles uses PowerPC CPUs. If you're new to assembly, don't go learning Intel x86 assembly first, PowerPC is much easier than the Intel processors.
As for script languages, I would include languages like Python, Perl, Lua and Ruby in their family. My personal favorite in the bunch is Python, but any other language would probably do for you. The reason why I include script languages in the list is that it will benefit you as a programmer in your day to day productivity. Even if you're main job is to write C++ code all day, there are many programmer tasks that can be automated or made easier by scripting them. Writing a small script can save you tedious steps. It pains me to see people writing a full C++ program for tasks like comparing items in different directories according to different criteria, a task that could have been written in Python in a matter of minutes. Anyone who had to dabble in the low level Win32 API can probably appreciate staying away, far far away in another galaxy.
So the categories would be (lowest level to highest level):
- Assembly
- C++ like imperative (portable assembly)
- Script language
- Functional language
So what would suitable choices be for the different categories? I've got some (and mentioned some already). They might of course not suit your circumstances, this is my very biased list.
Assembly languages
Out of necessity I've been reading PowerPC assembly now for a while. It's funny how when I started out I had to read gobs and gobs of x86 assembly on the xbox 1. Back then the Playstation 2 MIPS and the newly arrived xbox 1 that was based the intel processor were the major players. The small gamecube platform had that slightly arcane PowerPC platform, a trait it shared with the Apple computers. In a twist of irony the landscape is currently dominated by the PowerPC processors (PS3, Xbox 360 and Wii) while Apple recently deserted over to the Intel camp.
If you're doing console development, it is reasonably important to be able to read some assembly, for two major reasons. First to make sure that constructs that you use commonly are transformed into reasonable assembly code. Secondly you need to dive into assembly to debug those hard to find "release mode I've enabled all the compiler optimizations and now I have a bug" situations.
Perhaps not always useful, but definitely something that you as a console developer needs to be aware of. Recently I've also had the fun of starting to debug x64 bugs in our tools. I'm starting to like the 64 bit Intel platform more and more, they've now got a decent register set and you know that most of the features are always there. I just have to wrap my mind around the weird things again, like Gulliver's Travels little endian...
Portable assembly
This category is pretty much taken by C++. Unless you're on the xbox 360 platform exclusively you will probably have to wait a long time until you can write games in C#. Even there, it will probably take a little while until you can at least push the envelope a little in C#. One might think it's odd that I put C# in the same category as C++? In my mind C# really does excel in it's integration with visual studio and the win32 apis. Building windows GUI applications in C# is really streamlined and doing it any other language today seems to be much harder since Redmond really seems to make it harder. For a GUI frontend I would absolutely use C#, but it's much harder to justify it on a console runtime.
I think for the foreseeable future we will see C++ (and C) to be the prevailing languages in real time embedded systems, which (console) games can be seen as. It may suck, but you have to learn it.
Script languages
My advice in this category would be to learn at least one language that can help you be more productive. A lot of day to day programming work (and some games designer work) includes one off tasks. Perhaps unify the naming convention for normal textures in the source repository so that you don't have to save metadata for the images. For this, the artists might have saved the images with a variety of names, but you want to move them all to follow one convention. We might talk about thousands of files here, something that you either have a very bored monkey do or write a short script to do it for you over night.
For tasks like this, we really don't care about performance of the language itself. A 100 times slowdown might not be noticeable at all since the majority of the time will be spent in external programs, copying assets or just waiting for user input.
My personal favorite in this category is Python, a reasonably mature language that's been around for a while. Some describe it as LISP light. After the initial learning hump, I feel that Python allows me to program almost as fast as I can think about concepts that I want to implement. Very rarely do I find myself thinking that this was cumbersome in Python. It is a little bit too easy to fall into the trap of programming C++ like programs in Python, at which point you loose much of the rapid development Python offers.
There are of course more choices, Perl is another language that has been around for a while. While it offers a lot of the power that Python also offers, I feel that it lacks in clarity and often you wind up with scripts that are impossible to read. Die hard Perl fans of course disagree.
Functional languages
Functional languages are really interesting. Languages like LISP, Haskell and ML are so much more powerful than regular C++ that it's like they're not even playing in the same league. One joke that hits close to the truth is:
ML is arguably the best language out there. Unfortunately the only thing you can do in ML is writing a better ML compiler.
The gist of it is that while functional programming languages are incredibly powerful, the tools and the runtime for these systems have traditionally been ... really sucky. Most of the languages have really bad tools and runtimes, at least when you compare them to Visual Studio for C++ and the standard runtime you have in C++. It's unfortunate since they would allow us to express ourselves much more succinctly and thus get stuff done faster. Ironically they also are much more suitable for parallelizing algorithms, today in an era where we're racing to make things go in parallel more and more.
There is however perhaps a little light in the end of the tunnel. I recently came across a research project at Microsoft calledF#. It's a functional language based on Ocaml and the .NET platform. The thing that attracted me is that it's the first language that I've seen that actually provides some useful development environment, the language distribution comes with a full integration with Visual Studio (the debugger, compiler etc). It can access the other .NET languages seamlessly as well. After dabbling around with it for a while I kind of got the same feeling that I got from the C# language. They've tried to cram too much in there and had to do too many compromises to really feel like a slam dunk. The whole type inference in F# gave me a sour taste in my mouth since it caused you to rewrite your algorithms if you wanted them general (which causes you to either make the code more complex or duplicate the code which defeats the whole purpose). Gah. Perhaps they will fix this in later editions of the language...
In closing
While I don't think going crazy and learning all the languages out there is a good idea, neither is knowing only C++ a viable option in my opinion. If you're a single language programmer, I would highly recommend to at least learn a script language like Python to help you in your day to day tasks and problem solving. Python also has the advantage that it is used in a large number of platforms and applications. For example the long standing script language MEL in Maya is slowly being replaced by Python.
In the end it doesn't really matter which language you learn, as long as you have a couple under your belt. So that you don't have to create a whole new makefile for that one off C++ project to parse an XML file to replace all the tags foobar to cake...
Some random links that are not really related too much
- Some jokes about programming languages.
- Structure and Interpretation of Computer Programs video lectures (on LISP).
- F# homepage.
- Stevey Yegge rant on dynamic languages, in public no less.
- Paul Graham on LISP.
- God wrote in LISP.
- Understanding Python video.
- Python 3k. The next version of Python.