KnowledgeHub
Questions
Tags
Users
Search
Alex Rivera
|
Logout
Edit Question
Title
Body
I'll start with an example. Here's an equivalent of List.fill for tuples as a macro in Scala 2.10: import scala.language.experimental.macros import scala.reflect.macros.Context object TupleExample { def fill[A](arity: Int)(a: A): Product = macro fill_impl[A] def fill_impl[A](c: Context)(arity: c.Expr[Int])(a: c.Expr[A]) = { import c.universe._ arity.tree match { case Literal(Constant(n: Int)) if n < 23 => c.Expr( Apply( Select(Ident("Tuple" + n.toString), "apply"), List.fill(n)(a.tree) ) ) case _ => c.abort( c.enclosingPosition, "Desired arity must be a compile-time constant less than 23!" ) } } } We can use this method as follows: scala> TupleExample.fill(3)("hello") res0: (String, String, String) = (hello,hello,hello) This guy is a weird bird in a couple of respects. First, the arity argument must be a literal integer, since we need to use it at compile time. In previous versions of Scala there was no way (as far as I know) for a method even to tell whether one of its arguments was a compile-time literal or not. Second, the Product return type is a lie —the static return type will include the specific arity and element type determined by the arguments, as shown above. So how would I document this thing? I'm not expecting Scaladoc support at this point, but I'd like to have a sense of conventions or best practices (beyond just making sure the compile-time error messages are clear) that would make running into a macro method—with its potentially bizarre demands—less surprising for users of a Scala 2.10 library. The most mature demonstrations of the new macro system (e.g., ScalaMock , <a href="
Tags (comma-separated)
Save Edits
Cancel