I was asked recently how long I thought it should take someone to become "proficient in a new programming language", assuming said individual is already proficient in a different language. In various contexts, people will throw out numbers like six weeks, six months, a year, or more. Obviously the answer depends greatly on what the questioner means by "proficient", as well as what languages are involved. But I think it's the wrong question.
There are several good analogies between spoken languages and programming languages. I've heard it said that a good (spoken) language learner can become conversational new languages very quickly, but the hard part (and the part that takes the most time) is figuring out how to apply that language within its native culture.
I have picked up a (very) little bit of Chinese here and there, and I know that "xiao jie" translates into English as "miss" and is used as a term of address for women. But I'm afraid to use it in practice (at least until I discuss the matter further with one of my Chinese friends), because I have heard that its appropriateness might vary depending on the specific context, as well as from where in China the listener hails, and first and foremost I do not want to offend anyone.
Similarly, a competent software engineer can certainly become comfortable with the syntax and mechanics of using a programming language in a relatively short time. Learning how to apply those concepts in such a way that experienced practitioners of the language feel comfortable reading and working with the code, though, will take more time.
Back in the .com heydey, I was working on desktop applications at Microsoft and looking for an entry into the web world in my spare time. A friend of mine was working at a web startup in DC, and they were doing Perl. I won't name names to protect the innocent, but my friend was and is a True Perl Expert. So while going through the process of learning Perl using (among other things) the Larry Wall book, I would periodically send him my code, usually quite impressed with myself, and ask him how I was doing. The reply always went something like:
"Well, yes, that would work, but it looks too much like C++. A Perl programmer would never do it that way."
Perl, it turns out, has a very distinct culture. Although I had learned the Perl language, I had not learned how to apply it within the context of that culture. I wasn't correctly using the language's idioms, shortcuts, and libraries, and the code I was producing was "turning off" a more experienced Perl hand. Framing the situation in terms of Webster's definition of "culture", I was not respecting the "shared attitudes, values, goals, and practices" of the Perl programmers' community.
I know how my friend felt. Since that time, I've had the opportunity to look at a lot of Java and C# code written by unreformed C/C++ hands, and it is sometimes quite amusing. My personal favorite -- and the deadest giveaway -- is consistent use of:
String s = new String("Hello");
But there are many more subtle signs, ranging from code formatting and indentation to how one writes a simple conditional expression, and, perhaps most importantly in this age of large platforms, not knowing which libraries and APIs are available. Finally, there is the issue of context: Using a language and its libraries to write toy programs to reverse strings is one thing, but using it to put together a scalable web application is an entirely different matter.
Before a programmer can become truly "proficient" in a team environment, (s)he must internalize this knowledge. There is really no substitute for time spent reading code and observing more experienced developers. To borrow again from the world of spoken-language learning, immersion will yield the best results.
Joel Spolsky has an interesting essay on the cultural differences between Unix and Windows. If we wanted to, we could do similar analyses of Java vs. C++ vs. .NET, C# vs. VB, and others. To take one hypothetical, a C# programmer can start writing syntatically (and even stylistically) correct Java code in short order. But to ask that programmer to immediately and independently stand up a web application using Spring, Hibernate, and Struts, with an automated Maven build, unit tests, and one-touch deployment, and make it follow all of the best practices of the Java culture so that others can effectively carry the application forward -- well, that doesn't strike me as reasonable regardless of how experienced that person was in C# and .NET.
In this time where many software developers are reevaluating their careers and techology portfolios (often not by choice), I'm not saying that folks should avoid putting themselves or other developers in positions where they have to adapt to new programming languages and cultures. Quite the contrary -- throughout my career, I have observed that there is much to be gained from a "cross-polination" of ideas between different parts of the software development world. I would suggest, however, that when we do go this route, we need to set realistic expectations for people making these changes.