-
-
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.t
I should add that this essentially works around the problem that
def test(implicit byName: => Foo) = byName
does not work (rejected by compiler).
Ah, I see. Nice!
Instead of
c.Expr[T](t.tree)
you can just writet.splice