Generation of boilerplate

upd. Macro paradise for 2.10 and 2.11 now features macro annotations that can implement the design that's discussed below.

The following excerpt from a development branch of LMS project illustrates a typical class of problems. Sometimes neither object-oriented, nor functional programming can overcome certain kinds of boilerplate:

trait TupledFunctions extends Functions with TupleOps {
  implicit def fun[A1:Manifest,A2:Manifest,B:Manifest](f: (Rep[A1], Rep[A2]) => Rep[B])
    : Rep[((A1,A2))=>B] = fun((t: Rep[(A1,A2)]) => f(tuple2_get1(t), tuple2_get2(t)))
  implicit def fun[A1:Manifest,A2:Manifest,A3:Manifest,B:Manifest](f: (Rep[A1], Rep[A2], Rep[A3]) => Rep[B])
    : Rep[((A1,A2,A3))=>B] = fun((t: Rep[(A1,A2,A3)]) => f(tuple3_get1(t), tuple3_get2(t), tuple3_get3(t)))

As outlined in the "Type providers" case study, one of the solutions to the problem is textual code generation. Often, it's the most obvious and the only accessible one. The aforementioned case study dwells upon the shortcomings of this approach: 1) unintelligibility of generated code, 2) poor extensibility, 3) sub-par maintainability of code generators - and proposes a solution that involves macro types.

However, there are situations when generating a single type will not save the day. Sometimes the way to go is to create multiple types and/or functions at once. We considered to introduce macro packages, but decided that macro types will be enough, since Scala objects already represent an abstraction equivalent to packages (and even supercede them, because objects can be nested and, as of such, can capture values from the enclosing lexical scope).

There are plenty of other situations when convenient facilities for boilerplate generation may come in handy. Just off the top of my head: enums, serialization/deserialization, lenses, zippers and so on.