Exercism is one of the many coding challenge sites available. Unlike many others, it doesn’t have an online code editor and you will need to download the site’s own software in order to use the site. What makes it worthwhile? In one word: mentors.
Each tracks consists of dozens of problems. Some of them are part of the “core” of the track and the rest of them are “extra”. Core problems have to be reviewed by a mentor after submission. I will get back to this point later on. The problems increase in difficulty as you progress, with the first one being the “Hello, World!” program. You will deal with string manipulation, data structures, control flow and several other concepts as you advance to more difficult problems. This progression in the problem’s difficulty is very suitable if you are starting to learn a new language.
Like I said before, to start working on the problems you will need to install a particular software from the site. It’s a command line tool that allows you to download and submit the problems. To use it, you will need a command interpreter like any terminal on Linux based systems or powershell on Windows. The site includes a nice guide to install and run it.
What makes it good?
While many people would consider a disadvantage that you can’t solve the problems online and that you even need a special tool in order to start using the site, overall I consider it a positive feature. While it will take you some time and effort to do it, you will learn useful skills like setting up your own coding environment and using the command line in the process.
But the greatest exercism feature are mentors. They are people experienced in a programming language that volunteer on the site to guide you and give you feedback on your solutions! They can help you learn and improve your coding beyond simple problem solving.
Let’s see how does it works with an example of my own experience.
A mentoring example
This is an example of how the mentor feedback of exercism helped me change the solution I originally came up with, improving the readability and style of the code. It’s a problem taken from the Scheme track.
The challenge was to write a leap year finder. They are special years that have one extra day (366 instead of 365) in order to account for the rotation of earth about the sun not taking exactly 365 days (it takes close to 365 1/4 days). We have leap years almost every 4 years – with some exceptions as we will see.
The problem instructions, taken from exercism:
We have leap years:
On every year that is evenly divisible by 4
except every year that is evenly divisible by 100
unless the year is also evenly divisible by 400
For example, 1997 is not a leap year, but 1996 is. 1900 is not a leap year, but 2000 is.
Initially, I came up with this solution by trial and error:
(define (leap-year? year) (cond ((= (remainder year 4) 0) (if (= (remainder year 100) 0) (if (= (remainder year 400) 0) #t #f) #t)) (else #f)))
It works… but it’s a bit cryptic. If it wasn’t that we know what’s being tested for, the body of the function isn’t clear at all about what’s being tested.
I’m sure I could have written a very similar solution with less conditional statements. But as it often happens, I was more focused on just getting a “correct answer”. But a correct answer is not necessarily a good one. We will see how the mentor helped me improve it.
The mentor was very nice about my clunky solution but instead of “accepting” it so that I just continued with the next problem, he gave me some cues to improve it. This is what I came up with:
(define (leap-year? year) (if (and (= (remainder year 4) 0) (and (or (not (= (remainder year 100) 0)) (= (remainder year 400) 0)))) #t #f))
We see a great improvement. From using 3 conditional statements in the first solution to a single one! It’s also a lot clearer.
At this point I was very satisfied with my answer and I just wanted to move on. Luckily, the mentor came up with even more remarks.
The mentor made me realize that it wasn’t necessary to return true or false, those were the results of any boolean expression. He also mentioned that I was testing the same predicate over and over (if a year is divisible by a given year). Following his advice, I came up with:
(define (divisible-by? n) (zero? (remainder year n))) (define (leap-year? year) (and (divisible-by? 4) (or (not (divisible-by? 100)) (divisible-by? 400))))
The conditionals were dropped and the whole function is now just a single boolean expression. An now, with the use of a helper function, the body of the main function is almost a literal translation of the conditions given in the instructions.
By comparing the first and the third solution, we can realize the impact that the mentor feedback had while I was solving this problem. I learned about style, Scheme idioms (like zero?) and an overall better way to approach this problem.
Exercism is a coding challenge site suitable for starting learners or anyone starting learning a new language. It’s best feature are mentors. They will give you feedback and insight on your code that you wouldn’t get by just solving coding challenges on other sites. To use the site, you will need to install it’s command line tool. While that reduces the ease of use of the site, it has some advantages. You will need to set up your own coding environment locally and learn to use the command line, both useful abilities.