Ask HN: Learning multiple languages vs. mastering one

157 points by trtobe ↗ HN
Hi All. I am struggling to find/understand the best path to improve my knowledge/skills. I have a decent knowledge/experience in Java and now I am facing the dilemma either mastering Java or looking to other options to extend my programming language tool set mainly looking at: Javascript/Python/Scala/Kotlin/Elixir/Haskell/Swift.

I am interested in distributed system/data engineering and also in finding easily new well payed job. I know it's not possible to learning and master them all in a short time so I would like to pick 2. What I am struggling the most is how well to evaluate the language and get the best from it. Each time I pick one I end up giving up after 2 weeks as I always go back to Java.

The way I evaluate is simply by going to project euler and go through the problems from 1 to 20 then I don't know the next step to take from there. I find myself going through the crazy articles comparing languages and lose focus and give up.

Would be appreciated if you can share how you manage to focus on learning a new language or if it's worth at all learning/moving to a new language.

Update: forgotten also to ask what language do you advice and in 1/2 sentences why. thank you

136 comments

[ 3.2 ms ] story [ 249 ms ] thread
In my experience learning other languages makes you better at the ones you already know. You get exposure to different ideas, paradigms, and tools that you can bring back to your main language. For that reason I'd suggest looking at others.
I agree, especially if the other language uses markedly different paradigms. Like, if you already know Java, learning C# is not going to massively expand your horizons, the languages are too similar.

Instead, you should try something like a functional language (like Haskell or a Lisp variant), or a dynamically typed language (like Python), or a language with a different memory management model (like C, C++ or Rust). It will give you practical skills and expand your horizons on how to solve problems with programming.

last time I learned a new lang I did it by disciplining myself into following an Udemy course to the end

then tried to apply what learned in production (at work) as soon as possible so I don't forget

it is worth learning a new language to get a broader perspective on how to write software. you can easily write network services (that can scale later) in java, but not in javascript. you can easily create interactive demos using javascript (with html and css), but not with java.

as for how to stay focused, participate in a hackathon and build something using a new language. i find this helpful as it forces me to learn different features of a language. i don't like to learn a language by following tutorials which treat me like a baby learning to take its first step.

i have little idea about haskell, elixir, kotlin and scala, but here is some advice on the others: javascript: for web dev, interactive demos or quickly writing backend services python: writing scripts, backend for web dev, analyzing data swift: ios apps

On a diffrent topic, I wrote a bit on depth vs. breadth (but it was more of a book topic than language): https://news.ycombinator.com/item?id=17128854

For programming languages it boils down to: know the abstract stuff across most/many languages, but drill down on a small amount of languages/frameworks to be more productive.

I'd say: get to know Java and Python in-depth, select a few frameworks to know well (as languages by itself aren't the most useful thing when you are developing complete applications without reinventing the wheel). Java and Python have the advantage of a rich legacy, long term development, good cross-platform availability and broad support.

If you are specialising in the direction of high-efficiency or platform-specificity, I'd suggest Java + Elixir or Java + Swift.

I'd regard Scala and Kotlin as "Java-alternatives" for when you want to do Java without doing Java. Same goes for Groovy (and Grails framework). It's not a bad thing but doesn't automatically yield better results or gets you better understanding.

Keep in mind that languages by themselves are only useful if you have a supporting framework and knowledge of abstract programming concepts (which are language-agnostic).

When you want to "do Java without doing Java", it's good to use alternatives that have some present or like future adoption, such as Scala and Kotlin. You won't get that with Apache Groovy and Grails -- virtually no-one's upgraded to Grails 3 or started new projects in it, and the Grails 2 plugin ecosystem has almost died.
I used to be a Java dev (6 years ago)...

Over the last year I've been learning JavaScript + React (frontend) and TypeScript + Node.js (backend) for a side project. At times it's great because you can cobble together all these small modules to build something really quickly and other times.... everything gets updating so often and apis change.....oh I'm going to create a new project.... xyz module needs dependency abc...blablabla.

Also JS on the server is synchronous which is not natural for me to write it. I end up using async/await everywhere except for a few places.

So I've been thinking about to concentrating on a more stable eco-system so I can really master it. With that in mind, I've started learning Golang. Great if you're interested in web servers and distributed systems. It makes concurrency easy and it runs fast. Check out this post: https://grisha.org/blog/2017/04/27/simplistic-go-web-app/

For data you could use Python (#1) but I understand Golang is also a respectable in this arena but probably not the best.

Learn more languages.

Learning other languages increases the breadth and depth of your software development skills. You will start to understand the various commonalities between different toolsets, and learn new ways to improve code in other languages.

If you are having trouble with discipline, pick a project that restricts your language choice. Build a front-end web app using Javascript, or build an iOS app using Swift.

Don't learn a new language for the sake of learning a new language. Learn it because it solves a particular problem better than your existing skill set.

For example Node.js is good for tiny Web Services/API endpoints using an event-based model. Elixir for writing highly concurrent systems.

Sure, both of these can be done with Java -- since it's a general purpose language, but the result with more focused languages is a more succinct solution.

I suggest Elm into Haskell.

Elm will give you the ability to do frontend work while familiarizing yourself with functional programming concepts.

Once you're OK with Elm, go to Haskell, which is a great language to get exposed to plenty of radically new programming concepts.

Once you have done that, and considering you have experience in Java, you will have a much broader view of abstraction thinking.

Just to back this up, I found Elm to be a really good way to learn Haskell. I actually started with Haskell, but Elm allowed me to practice a lot of my functional programming skills and the different way of thinking without getting in my way too much, and in a fun environment with immediate feedback (frontend development). When I went back to Haskell I found it much easier.
I don't see how you can learn Elm without knowing the basics of Haskell.
That statement makes about as much sense as "I don't see how you can learn Haskell without knowing the basics of Elm". Arguably Elm is easier to learn from scratch since it is a younger language and does not have as much complexity baked into it as Haskell.
Trust me, you can. Elm was my gateway drug to Haskell. It's a great starting point, and the guide on the official Elm website offers everything you need to get started. Initially, I found Haskell overwhelming, but after spending a few months with Elm, which is a more narrow surface area, I found it much easier to sprinkle in Haskell specific concepts (typeclasses, applicative functors, monoids, etc).
During downtime between 2 jobs, I used to look at different languages for like half a day each, just to see what they did differently compared to the ones I already knew. I was mostly interested in concepts, not syntax.

This has helped me to be quicker when picking up new languages or even frameworks. Because, well, nothing is ever really new, right?

(Note that I would not recommend this strategy to a complete beginner. You need something to compare what you are discovering to.)

As for recommendations, I would suggest you look at what kind of problem you're trying to solve. If you could benefit from the infrastructure something like Java EE provides you, choose Java or kotlin (those are mostly interchangeable). For scripting, choose bash or python. For client-side web stuff, JavaScript. And so on.

It's obvious, you MUST learn multiple languages. The real question is " When should one learn a new language ?" As you have mentioned that you have a DECENT knowledge/experience with Java, your next language on the checklist depends on what you want to do next ?
Don't overlook at any books or tutorials from now. Go to the php docs alone. See stackoverflow for special queries only if stuck. Like any langs, start with low objectives. First try to do some maths, display the results. Then work with texts, try to alter contents by program. String, array, object, learn to create, and alter them. Later see by youself what kind of database type suits well your objectives. play with it (Flat files? json?). Wow you can pass external arguments by the url. (Big moment here ;) )

From there start to play with the internet, load remote datas, parse them, put them to your database. Then melt this all. Learn bash php scripting and unix, start to make system calls (exec, system, passthru...) enjoy the speed. Learn conditions (With just if you can do everything...seriously), Learn looping(while, foreach) , exit conditions and timing. Try to recreate basics tools: grep, cut, head, tail, cat.. you will see it is fairly doable and very funny to do.

Get bored? Do some javascript!

You will see personal ideas flowering at high rate. Still keep your objectives as low as you can. Small projects all aside.

Now you have all this in mind, open a book, check other sources code.

Learn security a bit. (Or not it all depends to your objective). Check good practices.

Close the books. Cut the Internet.

Get over this fancy libraries that anyone advise.

Open your editor. You are the internet. Have fun. ;)

What makes you think it's even possible to master a single language without learning others?

My experience tells me that monoglots reach false maxima because there experience isn't broad enough to realize that there are other maxima to climb.

Java is still, probably, my strongest language, but I strongly believe my craft would have stagnated around Spring/Hibernate if I hadn't taken the time to figure out how problems like typing, dependency injection, persistence, IO etc all work in other ecosystems.

Pick a language that is good for the market place you care most about. Mobile go with C or Swift. Science probably python. JavaScript if you like the web and if you like the perks of working in an Enterprise Java won't hurt.

(comment deleted)
I'd suggest to learn different _types_ of programming languages. That is, one object-oriented (like Java as you already have), one logical such as Prolog, one functional such as Haskell, you get the idea. In my mind learning several languages that all more or less belong into the same domain probably won't gain you any more insight into this field since all you're actually learning are subtle differences in syntax.
I would sort of do a hobby project in the following languages (in addition to Java for Object Oriented Programming, although something obscure like Smalltalk can be fun for an evening):

- Haskell, functional programming with static types

- Clojure (or Common Lisp), functional programming in a dynamic language (and understanding the AST-as-syntax-homoiconicity)

- C/C++, "low-level" programming (e.g. pointers, memory management, registers, the basics of compilers)

- Prolog, Logic Programming as a completely different paradigm

Then after you've "grokked" the pros and cons of these languages, pick one language to become good at. It doesn't matter if that is Java, Java is a fine language; but being exposed to different paradigms broadens your horizon in my experience, and sometimes the idioms and ideas are portable. Personally I've done a lot of back and forth between Java, Python, Clojure and R . If the choice is mine I usually pick Clojure, but not always. Statistics and datascience I still do in R or Python just because the sheer amount of documentation and libraries available. I guess I've been influenced too much by Rich Hickey but he asks "would you rather become good at programming or at problem solving?", and for me it's the latter. Language paradigms help you to recast problems onto a different frame of mind, but at the end of the day it's your ability to help further a cause/business/idea that counts. Just my 2 cents!

Could you give some examples of projects for which each of those language (types) are useful. Because I think it is important to choose a language fitting with the problem (or the other way around if it's exercise)
I'm going to respond even though not OP, because I had this same mindset for a long time.

A while ago I was posting on one of the "how do I learn math as an adult" threads that inevitably pop up here, and I got an absolutely wonderful response full of details and resources, but I asked basically the same followup question: "Thanks so much, this is great, but by the way, how can I use these things?"

The hard part about answering that question is that these are fairly abstract mental tools that affect your very perception of problems. I don't ever bust out Prolog or Haskell while in my day-to-day work, or even directly and consciously apply Prolog or Haskell-style constructs, but I 100% approach problems differently as a result of knowing them. How can I demonstrate that? It's difficult. When I think about real work problems, I don't spend a lot of time doing some kind of meta-thought where I try to identify how I know to think that way. But I do know for example that my Java code ends up looking and feeling more Haskell-y when I'm done. And I know that my coworkers look at my JavaScript code for example and wonder how the hell I came up with a particular solution, and it's for the same reason: I just see it differently, because I've built up a more varied mental toolbox.

That may seem like a wishy-washy answer, but hopefully it has some use. Think of it like learning Latin or how to play an obscure instrument: they're not necessarily tools for application, they're for changing how you see language or music, or in our case, how you see problems.

EDIT: All of this isn't to say that discussions of languages in the context of a specific problem area can't be useful. Sasa Juric has a wonderful section on which problem domain Elixir excels at in "Elixir on Action," for example. I just think in many cases, as with Prolog and Haskell, the primary benefits appear at higher levels of abstraction.

I came across this article that talks about this topic. It basically says focus on 1. http://norvig.com/21-days.html
Great article, however it doesn't say that really (perhaps you missed this bit)

"Learn at least a half dozen programming languages. Include one language that emphasizes class abstractions (like Java or C++), one that emphasizes functional abstraction (like Lisp or ML or Haskell), one that supports syntactic abstraction (like Lisp), one that supports declarative specifications (like Prolog or C++ templates), and one that emphasizes parallelism (like Clojure or Go)."

(comment deleted)
There's a book: 7 Languages in 7 Weeks that tries to pick a language from different "domains" (functional, imperative, prototype...)

Might be what you're looking for, a quick way to asses the landscape.

As for mastery: yes, you need to be able to master at least one language, and plan to always master the language you are going to use the most.

Don’t learn languages, learn frameworks instead. Pick a problem and find the most popular frameworks that are used to solve it. Learning language just for the sake of it is useless.
In picking a language, look for

1. Ecosystem. You _will_ need help

2. Friendly (to you) syntax

3. Target to achieve (in your case, it would mean a language that is frequently used in distributed system/data engineering)

Regarding "I find myself going through the crazy articles comparing languages and lose focus and give up.", I hear you. I've been there. Pick two and run with them. Once you start learning a language, stop reading articles on what other languages you can be learning. There is always something better down the corner. That doesn't mean you lose focus and drop whatever you're doing midway. Persevere, and you will prevail.

Finally, my recommendation, based on your requirements would be

1. Python (for data engineering - numpy, scipy, tensorflow, pandas and whatnot)

2. elixir (for distributed systems)

Hope that helps. Good luck!

I've made this transition over the last few months.

For the past eight years, aside from dabbling on my own, I've been a .NET developer. I've worked in startups, agencies, and good-sized companies, and have delivered more projects than I can count. I've also given talks at user groups, and have delivered open-source tools. I wasn't an expert, but I'd say that I knew C# and .NET reasonably well.

However, I always felt a bit of imposter syndrome. While the .NET world is more open than ever, you still feel like you're an apple in an orange-infested world. Literally everyone else builds on Mac/Linux, and while the tools differ between languages a PHP developer would have more in common with a Python developer than they would with a .NET developer.

So, I left a senior role and took a standard dev role in a software house with zero .NET tooling, and have forced myself to learn different languages in anger, instead of restricting myself to only learning in my free time.

It's been hard, but I feel like I'm learning loads every day. I've also learned things I would've probably ignored if I was doing this in my free time, like Ruby and Rails. I still feel like an idiot most days, but I'm hoping that in the next few years I'll go from being a solid C¢ developer to a solid developer, and that alone will go a long way towards getting over that imposter hump.

So, my advice is to try and learn what you can on your own, but if you feel that you are better served by working with this tools "in anger" or around a team that really knows its tools then look for a job that both allows you to do this. Once you reach a point where you're comfortable in a language, move to something new, but keep that language to your free time.

You should learn C. Most current engineers don't, and therefore the fundamentals of things like memory allocation, data types, call stacks, etc. remain a mystery to them.

I have one other comment to make. In my opinion, being a strong programmer is mostly a "knack," meaning it's not a particularly teachable skill. Some people are just amazingly good at it. If you are, great. If not, I suggest acknowledging that and fashioning a career that doesn't rely primarily on programming skills.

Noob question: Is there room for below average programmers? If so, where?
I wouldn't think of it in those terms. Most programmers aren't "amazingly good" at it. So, I'd say most work as ... programmers.

I just wanted to make this point because I've repeatedly seen folks frustrated by others who just get things faster and ultimately make progress much more quickly in their careers.

I think it's useful/important to acknowledge that programming is a bit like sports. It's not fair, but some people start with an incredible genetic (or something) advantage built in. I've seen this time and again.

Just to add to this, what you might see as being "amazingly good" might simply be the ability to cobble together pieces of (bad) code from various libraries, without really understanding how things work under the hood.

Incidentally, the best programmer I've ever met (he co-authored a very popular programming language) happens to be one of the slowist typists I've seen. I once asked him why, and he said "because I have to think."

Take your time and have fun.

It really depends on what you personally believe means "amazingly good programmer".

For some it means writing hard mathematical algorithms. For some it means writing the efficient and secure low level code. For some it means solving real problems fast by efficiently glueing existing code. For some it means great communication/management with 30 other programmers on team.

I think it is more about finding who you really are and following that than trying to become some dogmatic idea of what "amazingly good programmer" is.

Find your niche. The bubble effect is strong in all of us.

> Is there room for below average programmers?

Yes!

If we assume that about a third of all programmers are "average" (whatever that means), another third is "above average", and one third is "below average". So, it's not actually a tiny minority, despite what Hackernews might make you think.

Programming consists of many different aspects: creating an architecture, designing algorithms, implementing them, hunting bugs, testing etc.

If you think you are "below average" in one of these areas, you can team up with other developers who are good in that area, and let them guide you.

For example, I work with somebody who is amazing at digging deep and really understand the low-level nitty gritty of bugs. But, they are not that great at building high-level abstractions. So when a task involves building high-level abstractions, we discuss these abstractions beforehand, write some mock examples that use the new abstractions etc.

Some developers aren't good at low-level stuff, but build great user interfaces. Some don't do that very well, but shine when it comes to automation.

To sum it up, "below average" programmers can be very useful to an organization with the right amount of specialization and collaboration/mentoring.

I've been slowly learning to program as a side project (I'm an architect, buildings not IT) and considering to adapt my career to a suitable niche in IT. Front-end/UI-UX seems to be the answer.

I used to hate (the lack of elegance of) JS but I got used. After a lot of dabbling, I'm still between React and Vue. While I prefer Vue, all jobs ask for React. Framework marketability seems to be crucial when/while you perceive yourself as below average.

A person can be an average programmer, and still a superstar if they are an expert in a problem domain. As an examples, shipping / order fulfillment has many weird nuances - things like tariffs, dealing with dangerous goods, differing address systems, etc. Expertise in practically applying the code is extremely valuable.
I'll throw out my $0.02, which is C is a terrible language to learn. Much of writing "good" C revolves around knowing all the pitfalls to check for, then dealing with the archaic error handling mechanisms. Tomes have been written on the subject of proper error handing in C.

> fundamentals of things like memory allocation, data types, call stacks, etc. remain a mystery to them.

I don't think C is especially good at teaching these.

Unless you roll your own malloc, the big difference in memory allocation in C vs. say, Java is that C requires the programmer free memory after allocation on the heap. This is more tedious than difficult.

Data types exist in other languages. You can unpack raw bytes of data using Java and simulate the behavior or unions.

You'll have to explain how call stacks are more exposed in C. Best I can think is calling conventions, but that's more the domain of compilers than language. Buffer overflow prevention, maybe (but again, I think that's more tedium to deal with).

C is great because it's a small language. But I don't think it's an especially educational language.

Yeah I just disagree. I actually think Java is a terrible teaching language. Folks for whom Java is the closest they come to the hardware tend not to understand the internals of how computers actually work well enough to do things like understand where bits fit into bytes or what happens if you recast an int into a double without converting the underlying data.

Many times that doesn't matter, but to me it's important to have a supple and complete understanding of the underlying ideas. Java fails at that.

When I referred to memory I meant more than malloc and free. It's things like understanding how an array of ints is laid out in memory and what happens when you treat it as an array of chars instead. If you talk about this to a Java programmer, their eyes are likely to cross.

Your argument seems more in the vein of "C programmers are smarter java programmers" while ignoring the actual discussion, which is C is not a good teaching language. Yeah, you'll learn some stuff by virtue of blindly running over the language's landmines. I don't consider trial by fire to be a great way to learn.

> It's things like understanding how an array of ints is laid out in memory and what happens when you treat it as an array of chars instead.

This is one of said landmines, as the size of both is architecture/compiler specific. The only thing you learn by stepping on this one is, "use fixed-width integers when you care about exactly how many bytes the value is."

lots of advice on languages...

I'll just say, pick something functional and something dynamic.

Then, for something that will get you to do a little bit more than euler, try using https://adventofcode.com/

Languages are moving so fast recently that mastery is something of a moving target in a lot of cases. Often using different languages can give you a better insight into how features in other languages can be used - e.g. learning OOP/classes while managing all the complexities of C++ can leave you slightly confused about the whole thing, but if you go learn some Java where it's forced on you, it makes a lot more sense in C++.
The problem with flitting between many languages is that these are very perishable skills. To be productive is not merely a matter of being proficient with the keywords and syntax, you need to have in your working memory vast swathes of the standard libraries so you know when to just use a standard function versus reinventing the wheel or spending all your time consulting the docs. This fades quickly if you aren’t doing it every day. I don’t think it’s really possible for most engineers to have more than 2-3 languages that they are really good at, whereas you can dabble in a dozen or more if you are just making small changes to existing code.

The real question is not which language is the best but what is the language and libraries most used in the industry/field you want to work in? Figure that out then go deep.

Javascript will open some doors for finding more dev jobs (probably not for data engineering)

Java was my first language, and i really only knew about object oriented programming. Learning to write functional code has really broadened my skillset