Macro Annotated Tuple

Scala is a very expressive programming language. Most of time few lines are good enough to suit the programmer needs. However, it is not always possible to escape situations where boilerplate is unavoidable. For instance, I firmly believe that there must be a prettier implementation for Scala tuples (Tuple2, Tuple3, …, TupleN). After playing with the new metaprogramming features for a while, especially Macro Annotations from Macro Paradise, I found that these tools could be useful to reduce this kind of boilerplate. From now on, I will be telling you my modest attempt to deploy the minimal implementation for Scala tuples.

What’s the Problem?

Well, the problem is quite straightforward. This is annoying boilerplate:

class MyTuple1[A](val _1: A)

class MyTuple2[A, B](val _1: A, val _2: B)


class MyTupleN[A, B, ..., N](
  val _1: A,
  val _2: B,
  val _n: N)

The involved pattern is very clear (MyTupleX requires X type parameters and X accessors) and that leads to a sequence of repetitive stuff. There’s no place for such an ugly code in a language which aims expressiveness.

Macro Annotations to the Rescue

Macro annotations from macro paradise are empowered to generate new types, in contrast with the classical def macros. This opens a huge range of new possibilities such as transforming the annotated type itself or even providing a brand new companion object for it, whose contents could depend on the original type. How can we use them in the tuple scenario? My approach consists of using a class as a kind of type pattern, which will conform the macro input. Then the macro will generate all the required Tuple types. This is easier to understand by showing the pattern:

@expand(30) class MyTupleα[Tα](val _α: Tα)

As you could imagine, expand is the name for the macro annotation. It takes a number as input, which corresponds with the number of types that we want to generate for the pattern (in this case MyTuple1, MyTuple2, …, MyTuple30). Then we can see the pattern, which uses an alpha to represent the variable positions. This character will be replaced in the sequence of types that will be expanded at compilation time.

I’ve just uploaded the sources to github. If you are used to def macros you will notice that the way to implement macro annotations is not very different, once you’ve declared the header:

class expand(val bound: Int) extends StaticAnnotation {
  def macroTransform(annottees: Any*) = macro Macros.expandImpl

In fact, this is just an annotation definition which contains a def macro inside. That definition needs to take a sequence of annottees. For our case, you can think of it as a sequence containing a single element: the type pattern.

The macro implementation is partially shown in the following snippet:

def expandImpl(c: Context)(annottees: c.Expr[Any]*): c.Expr[Any] = {
  import c.mirror._
  import c.universe._

  val q"new expand($b)" = c.prefix.tree
  val Literal(Constant(bound: Int)) = b

  // ...

  val classes = for {
    i   } yield q"""
    class ${newTypeName(name.decoded.replaceAll("α", i.toString))}

  c.Expr[Any](Block(classes, Literal(Constant(()))))

The most interesting thing to remark is undoubtly the use of quasiquotes (q”…”), both to parse the upper bound and generate the output classes. You may not be able to appreciate how amazing is this new feature unless you had to deal with the old manually generation of Scala ASTs. Really. Once we’ve made the new types, we just return them inside a block.


Macros are icebergs that hide the expansion encodings real size under the surface of the sea. In this case, we used them to generate a sequence of types whose size can be chosen by the macro user. By adopting this approach, the maintainability is clearly better.

Honestly, the current implementation to generate the tuples is very ad-hoc, but I think that the pattern idea could be generalised to deal with more complex structures than the one shown in this post. By doing so, the number of lines required to implement this kind of boilerplate, that we can find in Functions as well, would be reduced to a minimum.


Speech… What?

There’s no other way to start this blog than talking about Speech. Well, you may be wondering what it is. Indeed it’s a difficult question to be answered in a few lines, but it’s the project where I have been working on the last three years. As I have said, providing the best description for its understanding is not always straightforward, but here’s my modest attempt: “Speech is a programming language that empowers programmers to develop social web applications in a fast and easy manner.” But hey, hold on! I know what you’re thinking. This isn’t about social networks. It’s about developing applications for the society. Why another language? This question is not as difficult as the first one. We are confident that new abstractions are required to increase the productivity remarkably. In fact, you can find some applications on github to see it (I recommend you the Twitter one).  That’s it for today! If you want to read more about the topic, please refer to the Speech official blog. From now on, I’ll be telling what does this project mean to me. And that lead us to Habla Computing.

Habla Computing is the startup where I work. That’s the place where I learnt that Java was not modern at all (what a surprise!), that you can program with immutable variables, that macros are not always as dangerous as you saw in the university and that there’s a community with amazing hackers ready to answer your weirdest questions. As you could guess, I’m talking about Scala, but it’s not only about this great programming language. This is just an entry point for one to find out that there’re other choices. Better choices. At every level. However, don’t misunderstand me. It wasn’t a smooth process. Getting Speech embedded in Scala was really hard for every member of the team. Anyway, we made it and it has been a worthwhile.

Perhaps you didn’t notice it, but this was just an introduction post. An unusual one, I guess. But it tells my nearest roadmap, the one that led me to restart my PhD studies. Didn’t you know that this is about a doctoral thesis? Then, read the about notes. See you soon.