Earlier this year, I had a conversation with Andy Hunt and Dave Thomas (joint authors of The Pragmatic Programmer and original signatories of the Agile Manifesto). They recommended (and have suggested in the past) the practice of learning at least one new programming language a year.
The reasoning behind this practice has very little to do with marketing oneself or even using the language. In reality, the most significant benefit of learning a new programming language is the stretching of the mind and the creation of new neural pathways that allow you to look at problems in new and unique ways.
I've compiled this list of languages primarily because they are languages I'm interested in spending more time learning, but also because they exemplify specific language characteristics and programming ideologies very well.
So without further ado, this is a list of languages you should learn to stretch your brain:
1. Ruby
Ruby is built for programmer happiness. That can mean different things to different people, but it's the first programming language that I've come to love.
The interesting thing about Ruby is that it's designed to embrace Object-Oriented Programming.
OOP was created by Dr. Alan Kay, who once said: "Object-oriented programming to me means only messaging, encapsulating and hiding state, and extreme late-binding of all things." Ruby is good at this stuff.
Due to the nature of Ruby's message-sending-obsessiveness, it's an incredible environment to learn true OOP. I recommend Sandi Metz's wonderful Practical Object-Oriented Design in Ruby as an introduction to Ruby's strengths when it comes to designing objects and message sending.
Another mind-stretching feature of Ruby is arguably more divisive than OOP. Ruby embraces metaprogramming, which can be loosely defined as code that can reason about and generate other code.
Being able to manipulate programs via metaprogramming, while sometimes frustrating, can require an extreme paradigm shift in your mental model of the relationship between programmer and programming language.
# FizzBuzz in Ruby
# https://github.com/zenware/FizzBuzz/blob/master/ruby.rb
def fizz_buzz(num)
result = ''
result += 'Fizz' if (num % 3).zero?
result += 'Buzz' if (num % 5).zero?
puts result.empty? ? num : result
end
(1..100).each { |x| fizz_buzz x }
Resources:
2. Elixir
While Elixir might look a little bit like Ruby, it's very different. It's a functional programming language.
Elixir is a language that embraces an idea called the Actor Model, devised by Dr. Carl Hewitt. In the Actor Model, everything is an actor.
("Everything is an actor" sounds a lot like "everything is an object," but I'll leave such comparisons to academics)
Learning to think about actors is a challenging mental exercise that will lead to seeing problems in a new light.
Another mind-bending feature of Elixir is its relationship with Erlang. Elixir runs on the Erlang VM (BEAM), meaning that at some point most Elixir developers have to develop some comfort with Erlang.
I could easily run off on a tangent here, but the most interesting thing about Erlang (in my opinion) is its mind-boggling prowess when it comes to concurrency. Writing Elixir means learning to think concurrently, a skill that can be applied in a multitude of programming environments.
Finally, Elixir is a beautiful exemplar of a concept called pattern matching. Pattern matching is a very powerful functional language feature that enables you to interact with data in a very concise and safe way. Pattern matching is not exclusive to Elixir, so a solid understanding of pattern matching in your Elixir code will translate to other languages and problems easily.
# FizzBuzz in Elixir
# https://github.com/zenware/FizzBuzz/blob/master/elixir.exs
fizzbuzz = fn n ->
cond do
rem(n, 15)== 0 -> "FizzBuzz"
rem(n, 3) == 0 -> "Fizz"
rem(n, 5) == 0 -> "Buzz"
true -> to_string n
end
end
Enum.each 1..100, &IO.puts(fizzbuzz.(&1))
Resources:
3. Rust
Rust is an up-and-coming systems language. That means it's particularly suitable for writing software when performance matters.
Rust is a fast, compiled language that brings some new ideas to the table. It is expressly intended to solve a number of the memory safety issues that arise when writing C++, which is frequently used to solve similar systems programming problems.
In Rust, you can learn about writing low-level code that interacts directly with hardware, you can learn about concurrency, you can learn about a couple of different paradigms, and you can learn it all with relative safety.
One of the most attractive things about the Rust language is that it opens a problem space customarily associated with languages infamous for their pitfalls and arcane idiosyncracies to mere mortals.
Learning Rust forces you to learn about the machine running your code without forcing you to worry about solved problems.
One other brain enlarging feature in Rust is called macros. Macros are a form of metaprogramming that enables developers to write less code and be a little less specific when it's convenient. Not without caveats, macros are challenging to reason about and therefore can help you to develop a different perspective on the metaprogramming you've seen in languages like Ruby.
// FizzBuzz in Rust
// https://github.com/zenware/FizzBuzz/blob/master/rust.rs
fn fizzbuzz(i: u8) {
if i % 15 == 0 {
println!("FizzBuzz");
} else if i % 3 == 0 {
println!("Fizz");
} else if i % 5 == 0 {
println!("Buzz");
} else {
println!("{}", i.to_string());
}
}
fn main() {
for i in 1..101 {
fizzbuzz(i);
}
}
Resources:
4. TypeScript
You could make the argument that TypeScript isn't a language; it's a "superset" of a language. That's fine. It's still on my list.
For those who are unfamiliar (which would be hard considering its popularity), TypeScript is a language that compiles directly to JavaScript. It adds some additional features to the JavaScript language, but it still feels like JavaScript.
The brain stretching in TypeScript comes from the incremental approach in which it can be adopted and its focus on static typing. If like me, you come from a web background with languages like Python, Ruby, or PHP, static typing is generally a foreign concept. However, TypeScript is a friendly way to introduce yourself to this handy language feature.
Learning TypeScript will deepen your understanding of the JavaScript ecosystem, give you a strong vision of the future of JavaScript, and introduce you the benefits of static typing.
// FizzBuzz in TypeScript
// https://github.com/zenware/FizzBuzz/blob/master/typescript.ts
function fizzbuzz(num: number): string | number {
if (num % 15 === 0) return 'FizzBuzz';
if (num % 5 === 0) return 'Buzz';
if (num % 3 === 0) return 'Fizz';
return num;
}
for (let i: number = 1; i <= 100; i++) console.log(fizzbuzz(i));
Resources:
5. Haskell
Haskell is the most esoteric language on this list. It has lofty goals and ideals that make it excellent for challenging your brain.
Haskell is described as "purely functional" meaning that state is entirely immutable in this programming language. Learning to work with totally immutable state forces you to develop a wholly different approach to working with data.
Working with Haskell will result in developing some understanding of lambda calculus, which is relevant to all functional programming.
Many developers who work with Haskell also comment on the clarity of meaning and purpose experienced with reading Haskell. While this is subjective, the language itself tends to produce code that is very explicit and in many cases, obvious. No one gets upset when code is too obvious. Unironically, Haskell code tends to be very concise.
One of the most challenging concepts in Haskell is called a Monad. Monads allow developers to avoid typing excess code and string together multiple computations. The Haskell documentation frequently describes Monads as "a strategy for combining computations to produce more complex computations."
Monads are not entirely exclusive to Haskell, but Haskell is known as being a language in which they are well implemented.
-- FizzBuzz in Haskell
-- https://github.com/zenware/FizzBuzz/blob/master/haskell.hs
module Main where
fizzbuzz :: Int -> String
fizzbuzz x
| x `mod` 15 == 0 = "FizzBuzz"
| x `mod` 3 == 0 = "Fizz"
| x `mod` 5 == 0 = "Buzz"
| otherwise = show x
main = mapM (putStrLn . fizzbuzz) [1..100]
Resources:
While programming languages are simply tools and tools should not be blamed or praised in the place of those who use them, different tools do unlock new techniques.
By introducing yourself to new tools and the techniques they enable, you can become a more well-rounded and creative engineer. If you are curious and adventurous enough, you may even find language features and programming paradigms that you can bring back to your preferred language.
I'd love to hear if this list inspires you to investigate one of these five languages, or if there is one you think I missed! 🤠






Latest comments (97)
Static typing by Rust does its best to stay out of the programmer's way while supporting long-term maintenance. Many statically-typed languages put a significant workload on the programmer, forcing them to repeat several times the form of a variable, which obstructs usability and error handling.
It's not really a matter of power but a matter of what you're trying to do and how you try to do it. You could say that Python is "more powerful" because it comes with a large set of built-in libraries or that C++ is "more powerful" because it's much easier in short it’s really a matter of opinion.
According to my opinion use what you feel is best for your task if you are best with PHP and you don't want to learn Python then don't. If you're interested in what it's like then check it out. one thing u keep in mind don't learn it because it's "more powerful."
All the languages are my jam, except Rust. Rust frustrates me.
I do feel a ruby-esq influence on all the chosen languages.
With the exception of TypeScript been chosen over Coffeescript but maybe if this list was made a few years ago we would have seen Coffeescript here.
It's interesting to me what people choose as their language learning path.
I think we can say most Rubyist moved to Exlir and Go and not NodeJs.
I'm quite surprised to see Scala not on the list. I really enjoy the Scala community even though I have no interest in the language. I'll attend Scala meetup just for the inclusiveness of the community.
Ruby definitely influences my opinions, as I said, it's the first programming language I've really felt attached to - but I'm also trying expand my horizons so things like Rust and TypeScript are good for me!
I know I'm going to be roundly laughed out here, but a lot of the languages we see around us are the result of people trying to come up something better in terms of their perception to new tools available.
This is an old language, and one for the most part a forgotten one, ( especially after reading the comments about smalltalk ) but its still a 'secret sauce' used by some surprising majors in their early conceptual labs. ( maybe because it's in Reverse Polish notation, trying to disassemble by industrial spies it produces nonsense.) I liked it for producing ultra quick algorithm design and proof of concepts, but the ever growing provision of 'playgrounds' are replacing that need.
Yes I gave it away then. The language is Forth. If you're done with mind-stretching, finishing off the smorgasbord with a dip into it is seriously mind-calming. Originally designed for embedded astronomy electronics, it gives a swift path into meta-programming without even realising. Everything else is there.
There is a saying: " If you seen one Forth, you've seen . . . one Forth!" that's because its extensible in so many ways, that a lot of the newer languages discussed are doing what all these scattered Forths did anyway.
As a side note in closing, we often like to romanticise Ada Lovelace as a hero, being the first programmer as C Babbage only designed the system. We have an equivalent hero alive today in Elizabeth Rather, she was the first to actually implement Forth in code as it's founder Chuck Moore was more the devisor while they worked together in developing it. And she's still at the helm. Another parallel can be found in Delia Derbridge, the actual technician/musician who assembled the Doctor Who theme after Ron Grainger left the specification on her desk before going on holiday.
To be fair, how much it stretches your brain is subjective (and the article is tagged for beginners).
However, those are great additions and I'm going to look into Clojure. 👍
Great article! Thanks for writing. I've been working pretty exclusively with JavaScript for quite some time but am lately learning Dart to work with Flutter. I feel like just learning a new language helps me reason better about all kinds of problems, even old JavaScript related ones.
Dart and Flutter look really cool! I'm excited for them to support desktop, but I haven't done much for mobile myself.
That's a nice list. I'm stretching my brain with some Perl 6 programming. Perl 6 is very expressive and includes features like:
Here's my version of the FizzBuzz written in Perl 6:
My boss is a Perl developer, or at least was before he started writing Ruby, I really appreciate Perl's expressiveness. I've thought about picking it up to build some fun tools before! Thanks for including a code snippet!
Perl 6 (perl6.org) belongs to the same family, but it's a totally different language. Much more expressive, too.
When I read the title, I immediately thought „Erlang“ and „Haskell“. So I’m happy both are covered in a way. Also Ruby or Python are a good choice for devs that are experienced in statically typed languages.
I think the most important take away here is, do this to move yourself out of your comfort zone to really „stretch your brain“!
A nice list... am thinking of putting Rust on top of Typescript on my learning list
Some comments may only be visible to logged-in visitors. Sign in to view all comments.