This post is a followup of Roadmap towards non-experimental macros | The Scala Programming Language to initiate a discussion whether whitebox def macros should be included in an upcoming SIP proposal on macros. Please read the blog post for context.
Whitebox macros are similar to blackbox def macros with the distinction that the result type of whitebox def macros can be refined at each call-site. The ability to refine the result types opens up many applications including
- fundep materialization, used by shapeless Generic
- extractor macros, used by quasiquotes in scala.reflect, scala.meta, and
scala.macros - anonymous type providers
To give an example of how blackbox and whitebox macros differ, imagine that we wish to implement a macro to convert case classes into tuples.
import scala.macros._
object CaseClass {
def toTuple[T](e: T): Product = macro { ??? }
case class User(name: String, age: Int)
// if blackbox: expected (String, Int), got Product
// if whitebox: OK
val user: (String, Int) = CaseClass.toTuple(User("Jane", 30))
}
As you can see from this example, whitebox macros are more powerful than blackbox def macros.
A whitebox macro that declares its result type as Any
can have itâs result type refined to any precise type in the Scala typing lattice. This powerful capability opens up questions. For example, do implicit whitebox def macros always need to be expanded in order be disqualified as a candidate during implicit search?
Quoting Eugene Burmako from SIP-29 on inline/meta, which contains a detailed analysis on âLoosing whiteboxityâ
The main motivation for getting rid of whitebox expansion is simplification -
both of the macro expansion pipeline and the typechecker. Currently, they
are inseparably intertwined, complicating both compiler evolution and tool
support.
Note, however, that the portable design of macros v3 (presented in http://scala-ang.org/blog/2017/10/09/scalamacros.html) should in theory make it possible to infer the correct result types for whitebox macros in IDEs such as IntelliJ.
Quoting the minutes from the Scala Center Advisory Board:
Dotty, he [Martin Odersky] says, wants to be a âcapable languageâ rather than
a âlanguage toolboxâ. So it matters whether whitebox macros are being used to do
âScala-likeâ things, or to turn Scala into something else. So âwe will have
to look at each oneâ of the ways whitebox macros are being used.
Adriaan Moors, the Scala compiler team lead at Lightbend agreed with Martin, and mentioned a current collaboration with Miles Sabin to improve scalac so that Shapeless and other libraries can rely less on macros and other nonstandard techniques
What do you think, should whitebox def macros be included in the macros v3 SIP proposal? In particular, please try to answer the following questions
- towards what end do you use whitebox def macros?
- why are whitebox def macros important for you and your users?
- can you use alternative metaprogramming techniques such as code generation scripts or compiler plugins to achieve the same functionality? How would that refactoring impact your whitebox macro?