-
-
Save larsrh/3039449 to your computer and use it in GitHub Desktop.
| import language.experimental.macros | |
| import scala.reflect.makro.Context | |
| object Name { | |
| def nameplicitly[T](implicit t0: T): Name[T] = macro nameplicitly_impl[T] | |
| def nameplicitly_impl[T : c.TypeTag](c: Context)(t0: c.Expr[T]): c.Expr[Name[T]] = | |
| c.reify(new Name[T] { def t = t0.splice }) | |
| } | |
| trait Name[T] { | |
| def t: T | |
| } | |
| // now to test! | |
| Welcome to Scala version 2.10.0-20120702-060901-33936243bd (OpenJDK 64-Bit Server VM, Java 1.7.0_05-icedtea). | |
| Type in expressions to have them evaluated. | |
| Type :help for more information. | |
| scala> class Foo | |
| defined class Foo | |
| scala> implicit def foo = { println("o hai"); new Foo } | |
| foo: Foo | |
| scala> Name.nameplicitly[Foo] | |
| res0: Name[Foo] = Name$$anon$1@54009218 | |
| scala> res0.t | |
| o hai | |
| res1: Foo = Foo@d64ea8b | |
| scala> res0.t | |
| o hai | |
| res2: Foo = Foo@308f8cd8 |
Thanks, updated accordingly. Can you give me some pointers to further reading about what splice does exactly?
Oh, right, I was looking at that document and was confused about why eval didn't work as expected :) Thankfully, the error messages are very helpful.
What's the purpose (beside of learning macros)?
The initial problem came from @tonymorris, who had a problem with strict-only implicits (https://gist.github.com/3039030). After a quick discussion with @milessabin, I had the idea to try and implement it. It's basically a by-name implicitly.
If you declare nameplicitly as implicit, you also get an implicit Name[T] for any implicit T, like that:
def test(implicit byName: Name[Foo]) = byName.tI should add that this essentially works around the problem that
def test(implicit byName: => Foo) = byNamedoes not work (rejected by compiler).
Ah, I see. Nice!
Instead of
c.Expr[T](t.tree)you can just writet.splice