When I started my career, books with titles such as "Teach Yourself C in 21 Days", and "Learn Java in 7 Days" were pretty popular. I was impressed that people could read such books. I never thought I could learn a new language in such a small amount of time myself. Time has passed. I've come to realize that I'm not alone in that case. Those books just happen to stretch the definition of learning a new programming language - and I'm being polite. In this post, I'd like to detail a bit of my definition of learning.
What defines a new language?
Learning one's first programming language is a hard challenge. You need to learn a lot of different concepts: condition evaluations, loops, etc.! In the following, let's consider that one already knows at least a language.
The question is how similar the new language is, compared to the one(s) already known. Wikipedia has [a tentative comparison][https://en.wikipedia.org/wiki/Comparison_of_programming_languages], with a set of specific criteria. But for similarity, this is not enough. I can yet offer some hints from my own experience.
My studies curriculum included courses on C and C++. In total, they amounted to a couple of hours. That was not much, but enough to teach me foundational concepts e.g. pointers. When I had to learn Java for my job, I distinctively remembered that the syntax itself felt pretty similar. I didn't care about the different memory management system.
Likewise, when I had to write JavaScript, the syntax was again familiar. Loops and condition evaluations were the same, despite the obvious lack of types, of classes (at the time), etc.
The first hard time I had when trying to learn a new language was with Scala. Some features of the language were brand new to me e.g. type inference, variance, for-comprehensions, and implicit parameters. I found the last two quite weird at the time.
Note that while I now understand for-comprehensions thanks to Python, I still think implicit parameters are a bad idea.
From Scala and Java, Kotlin was a pretty straightforward path. Still, from where I stand, I see all those languages as more or less related.
But this seemingly "easy" streak stopped when I tried to learn Clojure.
Clojure has a different syntax, akin to LISP: instead of function(param1, param2)
, it's (function param1 param2)
. I did link:/focus/learning-clojure/[try to learn it^] for a long time, but to this day, I'm unable to read non-trivial Clojure code.
It's wrong to claim one can learn a language in a specific amount of time because it depends where you start from.
Learning what?
Another issue in the above books' claim is what the reader will be learning.
In the above section, I wrote a lot about syntax. When one considers that aspect, C, JavaScript, Scala, Java all are pretty similar. Learning the syntax is just a matter of days. But, there's much more.
Beyond that, one needs to know about the libraries: any non-trivial application requires a lot of common utilities e.g. date formatting, HTTP client, etc. While the language syntax can provide some of these utilities, APIs handle the rest. These APIs might be available out-of-the-box - Java's HttpClient
, by a standard library - Kotlin' stdlib, or by third-party libraries.
Some differences exist depending on the language's ecosystem. Java offers more choices of third-party libraries than in C#. They tend to change more often in JavaScript than in Java.
Regardless, learning a new language as a newcomer is about:
- Getting to know the APIs
- What features they provide
- Understanding their respective pros and cons
- Choosing the best suited to one's project
The next level is even more involved. When Java started getting popular in the enterprise world, some C developers made the jump. By reading a code snippet, one could establish whether a new Java developer or a former C one was the author. Curly braces on a new line were one clue.
But the definitive clue came from dereferencing local variables at the end of the methods:
public void foo() {
Object foo = new Object(); <1>
// Work with foo
foo = null; <2>
}
- Assign a value to
foo
- Make sure the
Object
instance is not referenced anymore
One should strive to write code the way the language designer(s) intended it. This is not the case of the above snippet. Learning how to write idiomatic way code is much more involved than learning the syntax. This requires a lot of practice, not two or three weeks.
Moreover, every language has an ecosystem of tools around it. Although "real developers don't debug", this is one of the first things I learn when using a new language. I know how to do it in JVM languages and client-side JavaScript. I didn't write enough Python code to learn how to debug unless you count adding print statements in my code.
Besides, tooling goes a long way beyond debugging. It includes, but is not limited to:
- What IDE(s) is (are) best suited to develop in the language? It does take ages to get productive using an unfamiliar IDE.
- Does one need to free memory, or has the language a garbage collection tool?
- How do you run the code? Does a runtime interpret it directly, do you need to compile it to a native executable, or is there something in-between like the JVM's or Microsoft's bytecodes?
Learning a language has different facets:
- The syntax
- The libraries part of it
- Writing idiomatic code
- The surrounding ecosystem.
What skill level?
The last issue is about which skill level one aims to achieve. Two years ago, I had to make a small albeit non-trivial update to a Python Flask application. Though I had touched Python once in my life, and more than 15 years ago, I was able to achieve my goal, thanks to Google Search. During the review, my colleague asked to use some idiomatic Python idioms and to fix the linter's warnings. Do I know Python? Not at all. And still, I managed to update an existing application without learning in a couple of weeks.
Now, imagine a different context. The task would be to create a new application from scratch. In that case, the learning part would probably have taken me more than weeks, books or not.
Learning a language for a couple of weeks doesn't make you able to start developing greenfield applications.
Conclusion
Beware of books that advertise the learning of a new programming language in an unrealistic timeframe. You learn by building on one's existing knowledge. It's going to take years of investment. You can probably shorten the duration by knowing other languages whose syntax bear similarities with the one learned. No more, no less.
Originally published at A Java Geek on October 4th, 2020