Tuesday, January 6, 2009

Many Languages or One?

This question comes up all the time: "Should you learn many different programming languages or stick to just one?" Many programmers will jump on this one with a quick answer. Of course you should learn many languages if you want to be a great software developer. We hear this advice so often that it requires no proof or explanation.

The first time I read the "learn many languages" theory it was in The Pragmatic Programmer: From Journeyman to Master:
Learn at least one new language every year. Different languages solve the same problems in different ways. By learning several different approaches, you can help broaden your thinking and avoid getting stuck in a rut. Additionally, learning many languages is far easier now, thanks to the wealth of freely available software on the Internet.
Of course this is good advice if, like the subtitle says, you're a journeyman programmer looking to become a master. Is this the same advice we should give to everyone, though? What about beginning programmers? I'm not so sure.

Generally speaking, beginning programmers fall into two categories:
  1. College students
  2. Self-taught programmers
For the purpose of this discussion I don't think it really matters which group you fall into (despite what I said before). If you're a college student, you probably don't have much choice but to learn the syntax of 6-8 different programming languages in your first couple of years of school. That shouldn't hurt you, because you won't learn much depth on more than one or two of them. If you're self-taught, you probably have more control over how many languages you learn.

Let's take a look at what you should concentrate on when learning a programming language:
  1. Basic syntax (data types, variables, operators, conditionals, loops)
  2. String manipulation
  3. Compound data types (arrays, linked lists, hash tables)
  4. Basic algorithms and libraries
  5. File input and output
  6. Processing files (plain text, HTML, XML)
  7. Error handling
  8. Paradigm-specific details (procedural, object-oriented, functional)
  9. Managing memory (manual vs. garbage collected)
  10. Multi-threading
  11. Database access
  12. Network communications
The list could go on, but I think it's just about everything you should know about a language before you can claim (for example, on your resume) that you know that language. Most good books on a given programming language will include a chapter or two on most, if not all of these topics. But you can't just read one book from cover to cover and say you know a programming language. You have to do the exercises and write some real code (at least a few projects) before you can make that claim. That takes some time.

Most college courses aren't organized to teach you everything you need to know about a language, either. A 10-15 week college course will either touch lightly on several of the topics in the list above, or it will go very deeply into one or two of them. You might take several courses before you've done enough projects in one programming language to really know that language well. Consequently, it takes a couple of years of college to get a really deep knowledge of any one programming language.

Many supporters of the "one language per year" doctrine will say that learning a new language is good because it forces you to think about problems in a different way. This is just a new way of saying "think outside the box." This is almost always good for experienced programmers. Learning new languages will help stimulate you to find better solutions in your main language.

However, "one language per year" is almost certainly bad advice for a beginning programmer. You don't need to start thinking about new ways of doing things if you don't understand the old ones. Learning your first programming language to the depth necessary to solve many different real-world problems will take you more than one year. It won't help you to learn the basic syntax of two languages if you can't solve problems in either one.

My final advice to beginning programmers is this: You should give your first language 2-3 years to really take hold before you branch out into other languages. If you want to be a good programmer you have to know how to do a lot of different things in the main language you work in. Problem solving skills are certainly important, but you need to be able to implement a solution to a problem. If you spend the first few years of your programming career learning the basic syntax of many different languages, you won't have the depth you need to solve real-world problems in any of them.


Rob said...

Yep. And then limit yourself to, perhaps, 3 of them. I consider learning more than one language for investigation purposes only. iow, to see what's out there. You may pick up a few ideas or techniques, maybe even find another language you prefer to use. Other than that, you don't need to become a "master of none". I'm pretty good at one compiling language, one scripting language, and one shell language. That's all I may ever need.

Now someone may come along and say something about getting a job in another language I don't know but that will always exist. I can't get interested in anything .NET or PHP so I would probably never become a master in them anyway unless someone hired me to do them and then I'd get good by force.

Bill the Lizard said...

Good point about compiled and scripting languages. It's definitely handy to know one of each type. If you know a scripting language like Perl or Python, though, I'm not sure how useful it is to still learn a shell language. I can't remember the last time I used bash (as a scripting language, not as a shell).

Once you're to the point of programming professionally, your employer will definitely be the biggest influence on what language(s) you learn. You should be extremely proficient in the main language you work in. You'll probably only look for jobs with employers that use languages you already know, and for good reason. Still, I've known people who have learned new languages because they got offers they couldn't turn down. Those guys weren't even journeymen, though, they were already masters.

Anonymous said...

more important that the language is the operating environment. Understand it well - learn its quirks.
It takes time to uncover hidden gems and deep gorges.

The environment could be win32, *nix , java or whatever else you are working on. Eventually your language is going to use the system to get the task done.

Once you understand what is needed the language becomes clear as it is only the how.

Bill the Lizard said...

I had originally started writing about languages and operating systems, and how you should choose one of each and stick with it, but the article would have been twice as long so I had to cut it down.

Most languages and developer tools are cross-platform these days. The difference the OS makes isn't so much in the language and tools you choose, but in how you use them to solve problems for that platform. Anyone who has ever tried to write cross-platform networking code in C or C++ knows what I'm talking about. Interpreted and VM languages like Python and Java make this specific example a lot easier, but there will always be OS-specific things you can point to in any language. You'll eventually have to deal with the OS on some level.

Good point.

Chris Rathman said...

The question of what's a good first programming language to learn is quite different from what's a good first language to teach. My own opinion would be that Python is the best first language for self learners, while Scheme is the best language for teaching (in conjunction with SICP or HTDP). But a lot would depend on what you are trying to accomplish (agenda).

As for learning multiple languages, I consider programming to be both a job and a hobby. In support of my job, concentrating on a single language (at least short term) is probably the way to go. For hobby purposes, dealing in multiple languages is the most satisfying and eye-opening. I do think that sticking with a single language for an extended amount of time is probably optimal. Otherwise you are just going to get confused.

How one goes about learning new PLs will vary. I do recall that my third PL was the hardest. I could keep two of them separate in my mind, but getting the third one to fit in the brain required that I really understand the common and distinct factors between the languages. Once you get past the third one, they get easier to pick up.

My own technique for learning PLs is to translate books that use one PL that I don't know into another PL that I don't know - attempting to learn two languages at once. For example, I've been trying to Translate SICP. Probably too tedious for others, but it is the best technique that I have found for myself.

Bill the Lizard said...

I hadn't thought of that, but I think you're right that a good language to teach yourself isn't necessarily a good language to teach (or learn from) someone else. Good point.

As far as work/hobby programming, I think a lot of people turn it the other way around. I hear a lot of programmers complain that they're forced to know too many languages for their job, then they turn around and use some other language(s) for their hobby projects.

If you switch programming languages too early and too often, you risk becoming a jack-of-all-trades who is a master of none. I really think that learning one language extremely well before you branch out can help you to learn other languages more quickly. If you know one language really well, you know what's important, you understand programming concepts, and you can concentrate on what's different about the new language.

Doing the exercises from SICP in different languages is an interesting technique. I usually use some of the problems from Project Euler.

John said...

When I was in college, the CS department deliberately taught nearly every class using a different programming language. The idea was make students focus on abstract concepts rather than language syntax.

I think their idea was backward. If you want students to focus on abstract concepts, teach the first few classes using the same programming language so they can learn the syntax and quit focusing on it.

Bill the Lizard said...

I think most CS departments screw this up in exactly the same way. They have the right goal in mind, but their solution is wrong. If they want to teach new abstract concepts, why are they making students learn the syntax of old concepts every term?

Your comment made me realize that maybe Java Schools have it right on this one.

Anonymous said...

I almost agree with this... However, I think that it's good to get at least passing exposure to several different programming paradigms early on in your career/education, before you get too set in your ways to really grok something completely different. After a year or so of Java, do something with Lisp/Scheme/ML/Haskell, or whatever -- just enough that you begin to see the possibilities that the different paradigm offers. Then go back to that first language and concentrate on it for a while... but you'll see and understand that language differently, and you'll be better able to recognize the strengths and weaknesses of that language.

Bill the Lizard said...

I think we only differ on the time scale. I agree that you need to experiment with different languages to be really well rounded, I just don't think that needs to happen early. I also don't think a programmer gets too "set in their ways" in just a couple of years.

The reason I think people should stick with one language for their first few years is exactly the reason that most people say experiment with different languages. You want to concentrate on programming concepts, not syntax. Most people think that experimenting with different languages is the way to do that. I disagree. I think that sticking with one language that you know really well allows you to think in that language, ignoring the syntax, and concentrate on the programming concepts.

If you really understand the deep programming concepts that you learn from your first language, you'll have no trouble grokking the concepts that other languages can teach you too.