Introduction to writing a Scala object mapping library

The past few weeks I've been writing an object mapping library in Scala. Just for fun. So, what is it all about?

At Infi, we started our first Scala project mid-2016. When it became clear that Scala might be one of the technologies used in the project, I jumped at the chance to be part of it. I’m always eager to learn new tech, and doing a project in a functional programming language was already near the top of my professional wishlist.

As always, when learning a new technology, I like to push the envelope to see where things start to break down. I think it's a nice way to get to know the limits of that technology. As it turns out, Scala is a powerful language, with a strong type system that lets you use many advanced concepts I won’t detail here (eg. type classes, high-level abstractions like the ones in the Typeclassopedia with the help of scalaz or Cats, generic programming with shapeless and much more).

The thing I want to discuss here is a common annoyance: mapping one type to another and the amount of boilerplate it takes to do so. How can we get rid of that silly, boring-to-write mapping code?

Some programming languages already have standard library functionality that limits the amount of boilerplate you need for type-mapping, especially the dynamically-typed languages (JavaScript and Python make it fairly easy). In other languages you may have to resort to libraries like AutoMapper or use runtime reflection.

Here's how I tried to solve that problem in Scala.

The problem

It might be familiar: you have two unrelated composite data types that share some fields with the same name and type, and you need to map an instance of the first type to an instance of the second type. For example:

Say you want to get a Bar instance from a Foo instance. This one is simple, right?

All clear, no doubt what's happening here. But as your types get more fields, more mapping code needs to be written:

Also, when more types get added that you want to map to and from, you'll get more lines that are a variation of the last one in the code above. Yuck.

In short: the amount of mapping code you need to write depends on two things:

  • The size of your data types (let's call this the quality axis)
  • The number of data types (the quantity axis)

Possible solution #1: mapping code, concentrated at one place

So... In keeping things DRY, you don't want to repeat the above kind of mapping code at each location you want to get a Bar from a Foo. You might create something like the Scala equivalent of a C# extension method that keeps all the boring boilerplate code in one place, separated from Foo, Bar and other future types to map:

You probably guessed it: as the number of classes that need mapping increases, the nl.infi.thingamabob.data.mappings package will grow over time, potentially becoming a maintenance burden. There might be a better way...

But what way is that? In my next blogpost I'll explore the use of the shapeless library for a possible solution to this problem. Stay tuned!

[Stefan is a software developer at Infi]

We zoeken een ervaren developer!

› Wil jij je hersens bij ons laten kraken?

Wil je iets waarmaken met Infi?

Wil jij een eigen webapplicatie of mobiele app waarmee jij het bij anderen maakt?

Waargemaakt door de nerds van Infi.
Nerds met liefde voor softwareontwikkeling en die kunnen communiceren. En heel belangrijk: wat we doen, doen we met veel lol!

Wij willen het fixen. Laat jij van je horen?

Voor wie heb je een vraag?