Unfortunately, the (only) existing answer is low on juicy bits, and comment links are broken. So let me try adding some juice here, because if there is no other reason, my own link, when I actually decide to do something with it in the future, seeing that this answer is at the top of every google search that I I do.
A virtualized pattern pattern, as already mentioned, is a rewrite of how the Scala compiler handles pattern matching. It served many purposes, and part of the "virtualization" meant that it was part of Scala's virtualized effort. This effort is a bit opposed to macros: it takes things that are βrunβ at compile time, and then move around to run time.
For example, given the correct definition in scope, do the following:
if (false) 1 else 2
instead of being compiled into bytecodes of branches and literals, or even optimized for the literal "2", it is actually compiled as the following statement:
__ifThenElse(false, 1, 2)
See the scala virtualized wiki for more information and some examples of what this might be useful for.
I said, however, that rewriting template templates served many purposes. Another important goal was to turn the spaghetti code, which was an old template, complete or special and corner cases and errors, into something that could be reasoned, expanded and improved more easily. So many problems were fixed in this rewriting that people simply looked at a list of problems that used sample code for questions related to the template and noted that the problems were βfixedβ when they worked. It has new bugs, but on a much smaller scale.
Now there is very little information about how the new template layout works, but basically it translates into several method calls that are "implemented" in the compiler with the Option monad. Then it goes into the optimization phase, which creates the optimal bytecode.
You can enter your own matches, although it is locked behind the -Xexperimental flag. Try the following code copied from the Scala test suite, with and without this flag:
trait Intf { type Rep[+T] type M[+T] = Rep[Maybe[T]] val __match: Matcher abstract class Matcher { // runs the matcher on the given input def runOrElse[T, U](in: Rep[T])(matcher: Rep[T] => M[U]): Rep[U] def zero: M[Nothing] def one[T](x: Rep[T]): M[T] def guard[T](cond: Rep[Boolean], then: => Rep[T]): M[T] def isSuccess[T, U](x: Rep[T])(f: Rep[T] => M[U]): Rep[Boolean] // used for isDefinedAt } abstract class Maybe[+A] { def flatMap[B](f: Rep[A] => M[B]): M[B] def orElse[B >: A](alternative: => M[B]): M[B] } implicit def proxyMaybe[A](m: M[A]): Maybe[A] implicit def repInt(x: Int): Rep[Int] implicit def repBoolean(x: Boolean): Rep[Boolean] implicit def repString(x: String): Rep[String] def test = 7 match { case 5 => "foo" case _ => "bar" } } trait Impl extends Intf { type Rep[+T] = String object __match extends Matcher { def runOrElse[T, U](in: Rep[T])(matcher: Rep[T] => M[U]): Rep[U] = ("runOrElse("+ in +", ?" + matcher("?") + ")") def zero: M[Nothing] = "zero" def one[T](x: Rep[T]): M[T] = "one("+x.toString+")" def guard[T](cond: Rep[Boolean], then: => Rep[T]): M[T] = "guard("+cond+","+then+")" def isSuccess[T, U](x: Rep[T])(f: Rep[T] => M[U]): Rep[Boolean] = ("isSuccess("+x+", ?" + f("?") + ")") } implicit def proxyMaybe[A](m: M[A]): Maybe[A] = new Maybe[A] { def flatMap[B](f: Rep[A] => M[B]): M[B] = m + ".flatMap(? =>"+ f("?") +")" def orElse[B >: A](alternative: => M[B]): M[B] = m + ".orElse("+ alternative +")" } def repInt(x: Int): Rep[Int] = x.toString def repBoolean(x: Boolean): Rep[Boolean] = x.toString def repString(x: String): Rep[String] = x } object Test extends Impl with Intf with App { println(test) }
The result without a flag is what you expect:
scala> Test.main(null) bar
With -Xexperimental , however, compilation of an alternative "engine" correspondence:
scala> Test.main(null) runOrElse(7, ?guard(false,?).flatMap(? =>one(foo)).orElse(one(bar)))
See also additional scalability information for PatternMatching and MatchMonadInterface .
Disclaimer: there was an extraction above and was performed from the Scala version on the main branch after 2.10.0, so there may be differences. Unfortunately, I lack a clean environment of 2.10.0 or 2.10.1 to test it.