I’d like to talk about a great website I found a little while ago, exercism.org.

I discovered it a while back, when I was trying to learn Elixir. That project got interrupted pretty badly by my Kubernetes migration, but I’m now back to it. I still want to learn a language a bit more suited to web development, but I’ve switched to Golang now. Mostly because, when I started looking at Elixir again, I had forgotten pretty much everything again. Plus, I also never really wrapped my head around functional programming.

So I got into Golang. The added benefit I’m seeing with choosing Golang over others is that with Kubernetes, a core part of my Homelab is written in it, and the same goes for some apps I’m running in it.

The ultimate goal is to write a simple web app with some CRUD operations.

But that’s just some explanation as to the Why of looking at Exercism again. I mostly want to show you around the site a bit, because I think it’s a great tool when learning a new programming language.

The core of Exercism is not to teach you a language, but to provide you with exercises to get in a bit of practice.

A screenshot of Exercism's dashboard site for a logged-in user. At the top, it shows a menu with the following entries: Learn, Discover, Contribute, More, Insiders. Below it is my login name, mmeier, with a 'See your journey with Exercism' link next to it. Below that follows the main part of the page, welcoming me with a 'Welcome back, mmeier!' heading followed by 'Where to start', with links to 'Continue learning on your tracks', 'Try your hand at mentoring', 'Get involved in the community' and finally 'Donate to help us grow sustainably'. To the right of that is another section headed 'Your Tracks', showing the two exercise tracks I'm currently enrolled in, the Golang track showing 30/141 exercises completed and the Elixir track with 59/168 exercises completed.

Exercism’s homepage for logged-in users.

A track, with one track per programming language, consists of a number of exercises. Some of these are just exercises, others are “learning Exercises”.

The track page looks like this, using the Golang track as an example:

A screenshot of Exercism's Golang track. It shows that 146k students are currently working on the Golang track. Below that is a grid showing my progress in the track. It's topped with the percentage of tasks I've already completed, 21.3% at the time of the screenshot. Below that are a total of 141 symbols. They're either empty white circles, green circles with checkmarks in them, and a single one showing a lightbulb. One more symbols shows a filled blue circle. The empty circles are unstarted exercises, the ones with the green checkmarks are completed ones and the blue one is in-progress, while the one with the lightbulb is a learning exercise. Below this graphic are some stats, showing that 30 exercises have been finished, 33 concepts have been learned and 33 concepts have been mastered.

Exercism’s page for the Golang track.

Each of the symbols in the center represents one exercises, with the initial green checkmarks being the exercises I’ve already completed. The empty white circles after that are the exercises I haven’t touched at all yet, and the one blue point is an exercise I’ve started but not yet finished. Finally, the lightbulb represents a learning exercise. These are exercises focusing on a certain concept, which generally have more steps and a more in-depth description.

Here is what an exercise page looks like:

A screenshot of the page for the 'Gigasecond' exercise. On the left, it shows the steps for working with the exercise, starting with 'Solve Gigasecond'. Below it is a button to solve it in the online editor, and below that is a field showing the exercism CLI command to download the exercise for local solving. Afterwards, still locked with a padlock symbol, come the follow-up steps of 'Dig deeper', 'Complete your solution' and 'Publish your solution'. On the right is the introduction describing the exercise and what needs to be done. See the link in the main text.

The page for the ‘Gigasecond’ exercise.

This is the page for the Gigasecond exercise. On the right is the description of what to do. Gigasecond is a normal exercise, so the text only contains a description of the task. In learning exercises, the text will also contain some introductions for a concept or two needed to solve the exercise. For example a description of for loops or how functions are defined and called.

The great thing about Exercism can be found on the left side, with the instructions on how to work on the exercise. While you can use an online editor, you can also use the Exercism CLI tool to download it and work on it locally.

The tool is open source and can be downloaded and configured following these instructions. Executing the command under “Work Locally” has this output:

exercism download --track=go --exercise=gigasecond


Downloaded to
/home/michael/projects/learning/go/exercism/go/gigasecond

This creates a directory with the following structure:

cases_test.go  gigasecond.go  gigasecond_test.go  go.mod  HELP.md  README.md

And that’s why I like Exercism: It’s not just a collection of exercises, but for every exercise, for every language, there are unit tests together with a small project setup, so you know when you’ve actually solved the exercise successfully.

Running go test in the directory shows the failing test cases:

--- FAIL: TestAddGigasecond (0.00s)
    --- FAIL: TestAddGigasecond/date_only_specification_of_time (0.00s)
        gigasecond_test.go:23: AddGigasecond(2011-04-25 00:00:00 +0000 UTC) = 2011-04-25 00:00:00 +0000 UTC, want: 2043-01-01 01:46:40 +0000 UTC
    --- FAIL: TestAddGigasecond/second_test_for_date_only_specification_of_time (0.00s)
        gigasecond_test.go:23: AddGigasecond(1977-06-13 00:00:00 +0000 UTC) = 1977-06-13 00:00:00 +0000 UTC, want: 2009-02-19 01:46:40 +0000 UTC
    --- FAIL: TestAddGigasecond/third_test_for_date_only_specification_of_time (0.00s)
        gigasecond_test.go:23: AddGigasecond(1959-07-19 00:00:00 +0000 UTC) = 1959-07-19 00:00:00 +0000 UTC, want: 1991-03-27 01:46:40 +0000 UTC
    --- FAIL: TestAddGigasecond/full_time_specified (0.00s)
        gigasecond_test.go:23: AddGigasecond(2015-01-24 22:00:00 +0000 UTC) = 2015-01-24 22:00:00 +0000 UTC, want: 2046-10-02 23:46:40 +0000 UTC
    --- FAIL: TestAddGigasecond/full_time_with_day_roll-over (0.00s)
        gigasecond_test.go:23: AddGigasecond(2015-01-24 23:59:59 +0000 UTC) = 2015-01-24 23:59:59 +0000 UTC, want: 2046-10-03 01:46:39 +0000 UTC
FAIL
exit status 1
FAIL    gigasecond      0.001s

The gigasecond.go file is the place for implementing the solution and looks like this in the beginning:

// This is a "stub" file.  It's a little start on your solution.
// It's not a complete solution though; you have to write some code.

// Package gigasecond should have a package comment that summarizes what it's about.
// https://golang.org/doc/effective_go.html#commentary
package gigasecond

// import path for the time package from the standard library
import "time"

// AddGigasecond should have a comment documenting it.
func AddGigasecond(t time.Time) time.Time {
	// Write some code here to pass the test suite.
	// Then remove all the stock comments.
	// They're here to help you get started but they only clutter a finished solution.
	// If you leave them in, reviewers may protest!
	return t
}

The solution to this is pretty simple:

func AddGigasecond(t time.Time) time.Time {
	return t.Add(time.Second * 1_000_000_000)
}

Running go test again shows I got it right:

PASS
ok      gigasecond      0.001s

Then, the solution needs to be uploaded to Exercism:

exercism submit ./gigasecond.go


    Your solution has been submitted successfully.
    View it at:


    https://exercism.org/tracks/go/exercises/gigasecond

Another screenshot of the page for the Gigasecond exercise, but now only showing the exercise steps box. The 'Solve Gigasecond' section with the online editor button and copy-able command for local solving has been replaced with a 'Exercise Solved' section, which shows that I've uploaded one Iteration via CLI and that it has passed the tests. The previously locked 'Dig Deeper' section is now unfolded and shows further steps I could do, namely requesting a code review and exploring other solutions uploaded by the community. Finally, there's a 'Finished with the exercise' section which has a 'Mark as complete' button at the bottom.

The exercise steps box after uploading the solution.

Each uploaded solution is executed by Exercism to verify that it passes the same test suite I’ve previously run locally. I’ve then also got options for requesting a code review or to look at how other people have solved the exercise.

Once clicking “Mark as complete” the exercise is marked as complete. As “Gigasecond” is a normal exercise, this doesn’t do anything besides giving me bragging rights. But for learning exercises, there’s a tree where later exercises are only unlocked after earlier exercises have been finished.

I like the concept for Exercism a lot. Both for my current adventures in Go as well as previous bouts of trying to learn Elixir, it was a great source of some relatively easy exercises. I’m not sure how good their learning paths for languages are, as I’ve always used Exercism as a supplement for books I was reading to learn the language. But I’ve been using it mostly to get more familiar with a language, just to write some code in it and get the syntax down.

Finally: Exercism is a Not-for-Profit and it’s open source, so throw them a few bucks if you can and find it useful. 🙂