Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is it possible to defer macro expansion until abstract type is bound to specific type

I might be using incorrect terminology, but here is example what I would like to achieve. Lets say I have the following macro:

def generateField[T]: AnyRef =
  macro generateFieldImpl[T]

def generateFieldImpl[T: c.AbsTypeTag](c: Context): c.Expr[AnyRef] = {
/**
 * here I'm looking at the type T by reflection to see now many members it has
 * and based on that I'm generating TupleN[Array[Byte], ...](null, ...)
 * where N is number of members in class represented by type T
 */
}

I'm planning to use only case classes as T.

When I use this macro with case class it works great, but now I'd like to add a level of abstraction:

trait WithGeneratedField[T] {
  val _myField = generateField[T]
}

The problem I'm having is that macro gets expanded when trait is being declared and at that point T is known as an abstract type 'T'. Is there any way to defer macro expansion until I mix-in this trait with something concrete? For instance:

case class MyClass(a: String, b: Int) extends WithGeneratedField[MyClass]

At the end my goal is to use macro to add a generated field to a case class. Maybe there is a better way of doing that?

like image 378
Jarek Odzga Avatar asked Nov 03 '22 17:11

Jarek Odzga


1 Answers

I would be surprised if this turns possible in 2.10.0.

With macro types or macro annotations (http://scalamacros.org/future.html) it should be pretty straightforward. We're going to work on these new flavors of macros as soon as we release 2.10.0-final, but it's hard to predict the ETA. Maybe winter of 2012 - spring of 2013.

like image 103
Eugene Burmako Avatar answered Nov 09 '22 13:11

Eugene Burmako