Learn a New Language!
Nowadays, the world around us is littered with calls for learning to program. They tell me if I learn to code it will change my life. A quick google search will give you a list of the numerous benefits of learning to code. If you’re like me, you may think, “I know how to code. I have been working as a software engineer for a while now. I am already an expert in my language/framework of choice.” Learning to code may be the beginning of the journey, but I posit that even mastering a language should not be the end. It may just be time to learn a new language.
Why?
There are several advantages to learning a new language.
Best Tool for the job
I don’t do a lot of work with hand tools, but I do have two toolsets at home. One of them is a large set that can be used to fix most things around the house. The other is a smaller set that is intended for working on electronics.
I feel that programming languages follow the same pattern. To be clear, I am not saying that one language is like a screwdriver and another is a hammer. While, sometimes that’s true, it’s often more subtle than that.
Both of my toolsets contain a set of screwdrivers. Let’s say I have two tasks to do: fixing a door for my bedroom and replacing the hard drive in my computer. In theory I could use either set of screwdrivers to do either job. In fact I have done so before in the name of convenience. However, in most cases one toolset or the other is clearly the best for the job.
Selecting a programming language for a project is like picking which set of screwdrivers I should use. Is the project a web API? Does it need to run threads concurrently? In parallel? Does it need access to external resources? etc..? Most modern languages will allow me to do any of these things, but depending on the situation, one of them might do it more easily, cleanly, or straightforward than the others.
Learn different ideologies
Values
Have you ever considered what the creators of your favorite programming language value? When I hover the about tab on python.org I see the following statement:
Python is a programming language that lets you work more quickly and integrate your systems more effectively.
Clicking on “Learn more about Python…” brings me to their about page. There I learn a little more about the values of python:
“Friendly & Easy to Learn”
“Open-source”
From microsoft’s dotnet website:
“Free. Cross-platform. Open source”
“A developer platform for building all your apps.”
“One platform. Your skills, code, and favorite libraries apply anywhere you use .NET.”
Diving into their languages page they describe the languages themselves in more detail.
C# is a simple, modern, object-oriented, and type-safe programming language.
Do either of these sets of values match what you value in your next project? Or maybe they just resonate with you personally. Or maybe they match what your team or your company values. If so maybe that’s a good language to learn.
Syntax and Semantics and Style
The syntax, semantics, and preferred style of a well designed language should depict the values of its developers.
Most languages publish style guides that help developers learn the recommended ways to write clean code. See, for example, Microsoft’s Coding Conventions document or Python’s PEP 8.
Some languages also use linting to help developers by automatically styling code. See, for example, Haskell’s hlint or Javascript’s ESLint.
Other languages, such as Go, further promote clean code by enforcing strict syntax.
Do the language snippets (taken from Rosetta Code) below depict the values of each language? Do any of them depict something you value?
C#
static int Factorial(int number)
{
if(number < 0)
throw new ArgumentOutOfRangeException(nameof(number), number, "Must be zero or a positive number.");
var accumulator = 1;
for (var factor = 1; factor <= number; factor++)
{
accumulator *= factor;
}
return accumulator;
}
Go
func factorial(n int64) *big.Int {
if n < 0 {
return nil
}
r := big.NewInt(1)
var f big.Int
for i := int64(2); i <= n; i++ {
r.Mul(r, f.SetInt64(i))
}
return r
}
Haskell
factorial :: Integral -> Integral
factorial 0 = 1
factorial n = n * factorial (n-1)
Javascript
function factorial(n) {
//check our edge case
if (n < 0) { throw "Number must be non-negative"; }
var sum = 1;
//we skip zero and one since both are 1 and are identity
while (n > 1) {
sum *= n;
n--;
}
return sum;
}
Python
def factorial(n):
result = 1
for i in range(1, n+1):
result *= i
return result
Learn new ways to solve problems
Learning a new language introduces you to new approaches to problem solving. One clear example of this is moving from an imperative language to a functional language.
Functional programming is a style of programming where data is stateless and immutable; whereas, imperative programming deals with stateful data. With that in mind, how would you write an application that prompts the user for input in an imperative style? What about in a functional style? If you are not familiar with one style or the other, the answer may take some time to comprehend. Yet, once you do, it will change the way you think about state and mutability regardless of which framework you are using at the moment.
There are many other differences when moving from language to language:
- Dynamic/Static typing
- Explicit/Implicit typing
- Variable scopes
- Functionality of loops
- Built in implementations of data structures
- Objects, inheritance
- etc…
Having a grasp on many different ways to approach a problem gives you flexibility and allows you to be creative. You are able to identify the advantages and disadvantages of various approaches and select the right one.
Decouple from minute details
Learning a language allows you to see a problem, solution, algorithm depicted in multiple ways. Note the following snippets (from Rosetta Code) in python and haskell.
Python
from operator import mul
from functools import reduce
def factorial(n):
return reduce(mul, range(1,n+1), 1)
Haskell
factorial n = foldl (*) 1 [1..n]
Though the syntax is different, both of these implement factorial in the same way. They both use a fold to calculate multiplication on a list from 1 to n.
Take a look at Rosetta code’s Functional C# implementation:
static int Factorial(int number)
{
return Enumerable.Range(1, number).Aggregate((accumulator, factor) => accumulator * factor);
}
While this works, I personally would take the approach from the “Learn Different Ideologies” section above or a recursive variant of it.
The point is that if you know more than one language, you are not restricted to the context of that language. You are free to focus on determining the best algorithm to solve your problem. Then you can implement it in whichever language or framework best fits your needs.
Bleeding edge eventually becomes legacy
Unfortunately aging is a fact of life. At some point your code will be legacy. Your language or framework of choice will be, too. Technology is a fast paced field. We innovate, we seek feedback, and we iterate. New ideas, new patterns, new ways to do things appear quickly and often. With time new, more modern tools become the new standard, and the tools we have been using become less and less applicable. They are the right tool less and less often, until they become legacy, deprecated, or just “not the recommended way”. For example, how often do you write RPG? Or Pascal? Or Fortran? Except maybe in a few circumstances, these are not even considered by most developers for new projects. Yet, at some point, these were the bleeding edge of technology.
Call to action
I hope I have inspired you to go learn a new programming language. Not only does learning new languages allow you to build new projects the best way you can, it will also improve your capabilities with your current languages. It will change the way you approach problems and make you a more rounded software developer.