Writing macros which generate statements

Viewed 283

With intention of reducing the boilerplate for the end-user when deriving instances of a certain typeclass (let's take Showable for example), I aim to write a macro, which will autogenerate the instance names. E.g.:

// calling this:
Showable.derive[Int]
Showable.derive[String]
// should expand to this:
// implicit val derivedShowableInstance0 = new Showable[Int] { ... }
// implicit val derivedShowableInstance1 = new Showable[String] { ... }

I tried to approach the problem the following way, but the compiler complained that the expression should return a < no type > instead of Unit:

object Showable {

  def derive[a] = macro Macros.derive[a]

  object Macros {
    private var instanceNameIndex = 0

    def derive[ a : c.WeakTypeTag ]( c : Context ) = {

      import c.universe._
      import Flag._

      val newInstanceDeclaration = ...

      c.Expr[Unit](
        ValDef(
          Modifiers(IMPLICIT), 
          newTermName("derivedShowableInstance" + nameIndex), 
          TypeTree(), 
          newInstanceDeclaration
        )
      )

    }
  }
}

I get that a val declaration is not exactly an expression and hence Unit might not be appropriate, but then how to make it right? Is this at all possible? If not then why, will it ever be, and are there any workarounds?

1 Answers
Related