Looking back at the past twenty five years, I've definitely learned a few new languages and some of them well. I've also failed with a few languages in the sense that I gave up, lost interest, or did not follow through with them.

First learning languages is both hard and easy. Mastering the syntax is typically easy, with the exception of languages that are just really complicated (Rust, C++, Scala) and "weird" in the sense that they just are very different from what you might know. But what is hard is absorbing the idioms and familiarizing yourself with enough of the frameworks and libraries that you need to get stuff done. That requires investing a lot of time.

Rust is the one that got away for me. I'm interested in it and appreciate what they are trying to do with it. I definitely sacrificed some time trying to shoot through tutorials, and tinker with it. But it just never happened. It took too long to get productive with it and I had no real business reason to pursue it.

All the languages I did master, there was a business reason and opportunity combined with an attitude of "how hard can it be?". That's my default attitude and you get surprisingly far with it. It's a naive form of deliberate arrogance. If you allow yourself to get intimidated by other people's code, it becomes an obstacle. I'll typically get dragged into some project with existing code and I'll just start making small changes and google my way through solving basic issues and try to figure out what the existing code does. The more you do this, the easier it gets. Just figuring out how the code works, how it is structured and why it is the way it is means you absorb things quickly. Ironically, bad code bases are easier to deal with as you don't get stuck assuming things are correct or even done properly. Just tinkering and fixing code like that is usually not that hard. Make a small thing a little better, repeat.

Some examples:

I learned Kotlin by simply using the Java to kotlin converter in intellij for a backend project. I had read about the language and had liked it enough that I just sat down and started doing it on a Friday afternoon. I started with my main Java project and converted a few tests. Two hours in I was sold on this. It was just too easy and I liked the code that came out a lot better than the original Java code (less verbose) and my tests still passed. A week in I just decided to go all in and convert any Java code I dealt with to Kotlin. Being able to go file by file and class by class really helped me here. It barely slowed me down. 3 months in I had tens of thousands of lines of code converted and I started getting good at it. That's now five years ago and I no longer deal with Java and maintain several kotlin OSS libraries. It's my main language.

Example 2: I inherited some frontend project written in Javascript. It was a messy code base and it was now my problem to sort out. After mastering enough Javascript to work with the code base to make simple UI changes (it's basically just Java minus a lot of features), it dawned on me that I needed to up my game to be productive enough to do some major feature work on that project. When you have a nice code base, doing more of the same is a good way to do this but this code base was so messy that that was just not a viable path. It needed to be fixed, and I just needed to figure it out properly and I could not start from scratch and had to keep the UI alive at the same time.

So, I started upgrading it to typescript to fix it properly and introduce some level of sanity. This was a really messy JS project (as a lot of these projects are) and I needed to get past the constant "WTF does was this even supposed to do" stupid hacks that I was constantly fixing and dealing with. This was an iterative process of figuring out what the original javascript did and why and then doing it properly in typescript. So, I was effectively learning two languages at the same time.

Typescript is very easy to master. Like Kotlin, this is by design and as mentioned, I like things that have a compiler. So same process: just start converting existing code by changing the file extension to .ts. The typescript compiler helped me fix numerous obvious issues by simply chasing down warnings and annotating things with types and introducing some structure. Over the course of six months most of that js code base got converted and fixed, rewritten, or discarded and I got quite productive with it and was able to add major new features. It was still messy but at least it was my mess and I could work with it. Typescript and kotlin are very similar of course. Would use it again but I actually prefer kotlin-js lately.

I've dabbled with Php, Go, Scala, Python, and Ruby projects as well with different customers and while not my main languages I can work with code-bases for any of those languages and have done some productive things with all of those.

And in the distant past I came across C, Gopher (a haskell predecessor), Self, Smalltalk, AspectJ, prolog, lisp, and a few other languages. Basically, the hardest part is not the syntax but wrapping your head around different paradigms like logical programming, functional programming, imperial, and OO. It's not about things being better but about things being different and appreciating different ways of doing the same things.