You should definitely see Quasiquotes .
Quasiquadrats are used to perform two actions: to create trees and to compare with tree patterns. They allow you to express the tree you want to work with in terms of Scala equivalent code. You allow the quasiquaile library to work with how the Scala code maps to the tree graph, and that's good!
You can play with them in REPL, although the results may vary slightly in the macro universe:
scala> import scala.reflect.runtime.universe._ scala> showRaw(cq"p => p.name.is(Required(), HasLength(255))") res0: String = CaseDef( Bind( TermName("p"), Ident(termNames.WILDCARD)), EmptyTree, Apply( Select( Select( Ident(TermName("p")), TermName("name")), TermName("is")), List( Apply( Ident(TermName("Required")), List()), Apply( Ident(TermName("HasLength")), List(Literal(Constant(255)))))))
Another thing you can do with Quasiquotes is to actually use them for pattern matching.
scala> val fromTree = cq"p => p.name.is(Required(), HasLength(255))" scala> val cq"p => p.name.is($x, $y)" = fromTree x: reflect.runtime.universe.Tree = Required() y: reflect.runtime.universe.Tree = HasLength(255)
Now you have to be careful, because this template ONLY matches if the user named his template variable p .
scala> val fromTree = cq"x => x.name.is(Required(), HasLength(255))" scala> val cq"p => p.name.is($x, $y)" = fromTree scala.MatchError: case (x @ _) => x.name.is(Required(), HasLength(255)) (of class scala.reflect.internal.Trees$CaseDef) ... 33 elided
Instead, you'll want to be more general:
scala> val cq"${p1:TermName} => ${p2:TermName}.name.is($x, $y)" = fromTree p1: reflect.runtime.universe.TermName = x p2: reflect.runtime.universe.TermName = x x: reflect.runtime.universe.Tree = Required() y: reflect.runtime.universe.Tree = HasLength(255) scala> p1 == p2 res2: Boolean = true
And of course, if you did this as part of the pattern matching, you could do:
case cq"${p1:TermName} => ${p2:TermName}.name.is($x, $y)" if p1 == p2 => ???
Keep in mind that Macros are a deep dark hole. If you are just starting out, expect to spend a lot of time getting your macro right. After this, we expect to spend a lot of time on edge cases.