A few weeks back, I became aware of Advent of Code, a site built by Eric Wastl. AoC is basically an annual 25 day programming challenge/competition which has run every December for the past three years. Since I had the time over the holiday break, I gave it a try. I started too late to be in the running for the leaderboard, so I treated it as more of an “expanded kata” — a way to try out coding ideas in a relatively low-pressure environment. I have to hand it to Eric for creating such an engaging and entertaining set of puzzles. Having run the AoC gauntlet — and some parts were quite difficult, at least for me! — I feel I emerged a better programmer.
Given that I was already in the practicing/experimenting mindset, I kept thinking of Jeff Bay‘s “Object Calisthenics“. Up to that point, I had only minimal direct practice with this set of rules which, in his words, represent “far stricter coding standards than you’ve ever used in your life.”
As I went through the challenges, one rule in particular kept coming up: first class collections. Basically, instead of using raw collection types like List
or Dictionary
, you are supposed to wrap the collection in a class. Here is an example from Day 8 of AoC 2017, where you are supposed to manage a set of integer-valued registers:
class Registers { private readonly Dictionary<string, int> values; public Registers() { this.values = new Dictionary<string, int>(); } public int MaxValueEver { get; private set; } public int MaxValue() => this.values.Values.Max(); public void Increment(string register, int value) { int start = this.Get(register); this.values[register] = this.CheckMax(start + value); } public int Get(string register) { int value; if (!this.values.TryGetValue(register, out value)) { value = 0; this.values.Add(register, value); } return value; } private int CheckMax(int value) { if (value > this.MaxValueEver) { this.MaxValueEver = value; } return value; } }
In faithful Object Calisthenics style, the class has only one member which is the collection itself. Given that the collection is hidden and only accessible indirectly via public methods, a constrained set of operations grew out of this. Rather than being unnecessarily strict, to me this was a big improvement over some common alternatives where code dealing with raw collections gets spread widely in an application. (Think of how often you have seen code like the conditional get-or-add in the Get()
method land in three or four separate call sites.)
Despite Jeff’s permission to “relax and go back” to my old ways after the exercise is done, I can see myself continuing to strive for first class collections in more of my daily coding work.
For my full set of AoC solutions (C#, .NET 4.6.1), check out my advent2017 GitHub repo.