Types to the rescue

Source
I’ve always underestimated types, why should I wrap everything up into a domain specific type? I just need a String.

This is a brief story about how types are a safety net, protecting you from potential tricky bugs.

What inspired me to write this story was just this line of code:

final case class Counter(home: Int, away: Int)

Hum… this could be quite confusing, it’s easy to swap home for away and vice-versa. So I went ahead and created value classes for it.

final case class Counter(home: HomeCounter, away: AwayCounter)
final case class HomeCounter(value: Int) extends AnyVal
final case class AwayCounter(value: Int) extends AnyVal

Nice! Job done! I just need to go through the compilation errors and that’d be it!

Guess what? It wasn’t that trivial.

Immediately win

Finding invalid test was my immediately win, I knew that someone at some point had set home instead of away, or home in both values, or any wrong possible combination that you could imagine. So when I was going through the compilation errors, I found a good few invalid scenarios.

val homeGoals: Int = 1
...
match score Goal(Home) shouldBe Counter(homeGoals, homeGoals)

Updating tests

As I was updating unit tests with valid scenarios I was getting failures and at a glance I thought that I was being naive in just replacing values for the correct ones, but it happens that those where valid failure tests. Our business logic was wrong!

Fixing issues

Ugh man, what have I done?! Now I have to go through all these complex logic and fix the real problem just because I had the great idea of making a “small” refactor.

But then I realize, this is great! Just by changing types I could see beforehand all the issues without pressure whatsoever :)

After fixing real issues that I found by changing types I have to say that it made all that business logic way simpler and easier to read.

Conclusion

Creating domain-specific types may seem an overhead when we are modeling, but I have to say it’s an investment and the return is bigger than what you would expect.

Hopefully, this brief story encourage you not to underestimate the power of domain-specific types using tags, value classes or whatever fits your purpose.