json"[$macros]" and StringContext extractor macros

238 views
Skip to first unread message

Christopher Sachs

unread,
Jun 13, 2012, 1:27:33 AM6/13/12
to scala-l...@googlegroups.com
First I want to say I'm really impressed with how macros are shaping
up. Nice work guys. I can tell a lot of sweat and love has gone
towards wrangling this beast into its new cage. I'm grateful for it.

For my part I implemented a json"" string interpolation macro. I'm
pleased to say that it was fairly straightforward after reading the
SIPs. The biggest stumbling block I foresee macro writers encountering
is structuring their code around path-dependent types. I don't think
it's inherently difficult to do so, but the patterns differ from
traditional OO-design principles and need to be disseminated. Cakes
_do_ compose using a combination of Singleton types and existential
types (and the occasional type refinement). But I digress.

I hate to chomp at the bit since I know a lot of things are still in
flux, but I'm having trouble implementing an extractor macro for a
StringContext member. The compiler appears to assume that extractors
are methods, and macro unapplies seem to violate that assumption. Or
I'm completely misguided. Are there any suggestions for why the
following doesn't work? Do I need to return a certain kind of Tree?

object Foo {
import scala.reflect.makro.Context
import language.experimental.macros
implicit class FooContext(sc: StringContext) {
object foo {
def unapplySeq(args: Any*): Option[Seq[Any]] = macro unapplyFoo
}
}
def unapplyFoo(c: Context)(args: c.Expr[Any]*):
c.Expr[Option[Seq[Any]]] = c.reify(None)
}

scala> import Foo._
import Foo._

scala> val foo"" = "whatever"
...
uncaught exception during compilation: java.lang.AssertionError
at scala.tools.nsc.typechecker.Unapplies$class.unapplyTypeList(Unapplies.scala:28)
...

Here's the code for the JSON string interpolation and matching macros:
https://github.com/scalabasis/basis/blob/master/src/main/scala/basis/json/JSONMacros.scala

And an overview of the package for anyone interested:
https://github.com/scalabasis/basis/wiki/basis.json

Thanks again for the great work on macros, and on all the other
awesome new features in 2.10! And thanks in advance to anyone who can
help me figure out macro extractors.

--
Chris Sachs

P.S. If you want to see an example of composed cakes, look at matrix
spaces composition here:
https://github.com/scalabasis/basis/blob/master/src/main/scala/basis/algebra/MatrixSpace.scala

Jason Zaugg

unread,
Jun 13, 2012, 3:35:00 AM6/13/12
to scala-l...@googlegroups.com
On Wed, Jun 13, 2012 at 7:27 AM, Christopher Sachs
<chris...@gmail.com> wrote:
> Thanks again for the great work on macros, and on all the other
> awesome new features in 2.10! And thanks in advance to anyone who can
> help me figure out macro extractors.

Things go wrong here:

https://github.com/scala/scala/blob/master/src/compiler/scala/tools/nsc/typechecker/Typers.scala#L3111

The macro application is expanded before typedUnapply gets a chance to
see the parameter types of the unapply method.

You should raise a bug for this one.

-jason

Eugene Burmako

unread,
Jun 13, 2012, 4:23:32 AM6/13/12
to scala-language
https://issues.scala-lang.org/browse/SI-5903

Thanks for catching this bug. I'll look into it!
> Here's the code for the JSON string interpolation and matching macros:https://github.com/scalabasis/basis/blob/master/src/main/scala/basis/...
>
> And an overview of the package for anyone interested:https://github.com/scalabasis/basis/wiki/basis.json
>
> Thanks again for the great work on macros, and on all the other
> awesome new features in 2.10! And thanks in advance to anyone who can
> help me figure out macro extractors.
>
> --
> Chris Sachs
>
> P.S. If you want to see an example of composed cakes, look at matrix
> spaces composition here:https://github.com/scalabasis/basis/blob/master/src/main/scala/basis/...

Chris Sachs

unread,
Jun 13, 2012, 4:32:27 PM6/13/12
to scala-l...@googlegroups.com
As a workaround I had some success defining the StringContext extractor member itself as a macro that defined and instantiated an anonymous class with apply/unapply methods. It was rather unpleasant though so I'm glad I asked before pursuing that further.

Typers.scala is a little, uh, intimidating : ) I think I'll be spending some time in the compiler corner in the near future. And thanks for filing the bug, Euegene.

--
Chris Sachs
Reply all
Reply to author
Forward
0 new messages