Tips for Language Learning
In my last post, I shared several reasons to learn a new programming language.
If you need a little inspiration go there first.
In this post, I will share my approach to learning new programming languages.
A Note on Languages and Learning
Learning is a very personal thing. Everyone learns differently.
Languages in general are closely tied to learning.
Whether spoken, written, signed, or otherwise, languages are a method by which we interact with the world around us.
Our languages shape the way we learn and how we comprehend everything with which we interact.
Programming languages are the way we interact with computers.
As such, the programming languages we know shape the way we understand computers and software.
This, in turn, shapes the way we approach learning new things related to computers and software.
With this context in mind, I reiterate that this post is about my personal approach to learning new programming languages.
These suggestions are meant to empower you to find your preferred approach to learning languages.
Start with the Fundamentals
As with most things, when learning a new programming language, it is best to start with the basics.
Start by learning things such as:
- What are the primitive data types?
- What are other commonly used data structures?
- How is branching implemented (if statements, switch statements, ternary operators, pattern matching)?
- How do I create a function?
- Is looping implemented? If so, how?
- How is recursion implemented?
- How does the language handle I/O?
- Is the language object oriented?
- What is the lifecycle of an object?
- How do I define and instantiate objects?
- How are objects cleaned up/deconstructed?
- How do I create methods?
- How does the language handle asynchronous behavior?
- What does the language do really well that its developers love to share?
This list is not comprehensive but is a good starting point to help you determine what fundamentals of programming syntax are important to you.
Be careful when going through lists of questions like this.
Any one of these can take you down a rabbit hole, so determine how much time you want to spend on each question.
Ask youself, “Do I want to take time deep diving into each question, or do I want to get a short overview of each and deep dive later through other means?”
Compare and Contrast
While learning a new language it can be helpful to compare and contrast it to languages with which you are already comfortable.
Start by looking for similarities. Then seek context on why those things might be similar.
This can help you identify patterns between languages that help you learn more quickly.
Assuming I know java, I could recognize that looping in Java and C# is almost identical in functionality.
All I have to do is remember a few syntactic changes, and I understand both.
Next look for differences. Then seek context on why those things might differ.
Looping in Haskell is done through recursion. There is no “for loop” syntax like the syntax in Java.
What is it about Haskell that is not in the nature of Java that causes it to only use recursion for looping?
In many cases, the best way to learn is by doing.
In my mind “coding challenges” can be a broad range of things.
They can be mathematical challenges such as those provided by the Euler Project.
I also enjoy seasonal coding challenges such as the yearly Advent of Code.
I like mathematical challenges because they help me learn the mathematical fundamentals of a language.
They also help solidify concepts such as looping, recursion, and branching.
Small, Focused Projects
I like to do small projects that focus learning on a single skill.
For example, implementing the Baklava project which just prints a rhombus
is a good way to teach looping. Implementing Factorial is a good way to
When doing these smaller projects, it can sometimes be good to limit usage of libraries and helper functions built into the language.
For example, another project I often do is write a program that converts text to binary or hexadecimal.
Many languages and frameworks have libraries built in that will do this automatically, but avoiding those libraries for the scope of such
a project forces me to use and develop my understanding of more fundamental parts of the language or framework.
Coding challenges can also include code katas.
A kata is a software problem that is complicated enough to help you practice good software craftsmanship, but it is still simple enough that it
can be completed in a short period of time (generally less than an hour).
One example kata that I have enjoyed is the Yahtzee kata.
I think good coding challenges can also be found by looking for everyday problems or questions.
For example, my wife and I would play a simple game on public buses. Bus ticket IDs are six digits long.
If one of us buys a ticket where the sum of the first three digits of the ticket ID is equal to the sum of the last three digits, the other person has to buy the winner a small treat.
So, a ticket with ID 184229 would be a winning ticket, but 184334 would not be.
One day we wondered, “If we take four rides in one day, what is the chance that one of us would win that day?” This made for a good coding challenge (and helped distract us on the long bus ride).
When trying to learn a new language, don’t be afraid to “over-solve” a problem. That doesn’t mean that your solution should be overengineered.
It is still important to focus on good software practices, but it means that you don’t need to be afraid if there is an easier way to solve something than a writing program.
One problem I “over-solved” is family game night. My in-laws really enjoy playing uno and keeping score.
Keeping score of an Uno game on paper is really simple. Plus, I imagine that there are also several existing apps that would do it for me.
However, I was trying to learn
tkinter in Python 3, so I chose to write my own scoring program.
Disclaimer: I do not advocate “over-solving” a problem in production code.
Writing your own encryption library is a great exercise for learning, but I would not recommend including your own encryption library in production code when a good one already exists.
One thing I like to do after I think I have a good feel for a language is to assign myself a “final project.”
This project should be something that I cannot complete in a single sitting.
It should be a project I feel comfortable doing, but one that will make me think about how to strategically utilize the nuances of the language I am learning.
Personally, I like to implement the same final project in every language that I am learning.
This allows me to do the comparing and contrasting that I described in the section above.
Recently this project has been a web app that allows my wife and me to play a game of Clue with just the two of us and a computer player who does nothing more than hold cards and answer questions.
Abandoning a Project
One fun part about self-teaching is that the project or challenge you assign yourself might not fit the language you are trying to learn.
Don’t be afraid to abandon a project when you find that to be the case. However, before abandoning the project do a “postmortem evaluation.”
- Identify what about the language makes it a bad candidate for the project you were trying to complete.
- Identify what language might be a better fit.
- What about that language makes it a better fit?
- Is there a way that the language could be modified to make it work for this project?
- Is there a library or framework that provides this functionality? Could there be? Should there be?
Open Source Projects
One last thing you can do once you start to feel more comfortable with a new language is contribute to open source.
Most open source projects have a list of “issues” containing either bugs to be fixed or features to be added.
These issues (if well designed) are by definition scoped problems to be solved and will allow you to solidify what you have learned in a “real world” project.
Most open source projects also follow a pull request model. This means that your code will be reviewed for quality and best practices by a member of the project.
This is a good opportunity to get feedback on what you have been learning.
If you are new to open source, First Timers Only has some good resources to get you started.
Learning can be fun, exciting, and messy.
Whatever language you are learning, don’t be afraid to make mistakes.
Don’t stop asking questions.
Take time time to stop and evaluate what you have learned.
Доверяй, но проверяй. Translation: “Trust, but verify.” Or, in this case, follow the language’s best practices, but take time to verify why the creators and community have decided to do things this way.
I hope these tips help you get started with your language learning, but remember to find what works for you.
Never stop learning!