Skip to content

Instantly share code, notes, and snippets.

@larsrh
Created July 3, 2012 12:29
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save larsrh/3039449 to your computer and use it in GitHub Desktop.
Save larsrh/3039449 to your computer and use it in GitHub Desktop.
Attempting a by-name implicitly
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
@xeno-by
Copy link

xeno-by commented Jul 3, 2012

Instead of c.Expr[T](t.tree) you can just write t.splice

@larsrh
Copy link
Author

larsrh commented Jul 3, 2012

Thanks, updated accordingly. Can you give me some pointers to further reading about what splice does exactly?

@xeno-by
Copy link

xeno-by commented Jul 3, 2012 via email

@larsrh
Copy link
Author

larsrh commented Jul 3, 2012

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.

@hseeberger
Copy link

What's the purpose (beside of learning macros)?

@larsrh
Copy link
Author

larsrh commented Jul 3, 2012

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

@larsrh
Copy link
Author

larsrh commented Jul 3, 2012

I should add that this essentially works around the problem that

def test(implicit byName: => Foo) = byName

does not work (rejected by compiler).

@hseeberger
Copy link

Ah, I see. Nice!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment