Skip to content

Instantly share code, notes, and snippets.

@puffnfresh
Created March 6, 2013 02:44
Show Gist options
  • Save puffnfresh/5096299 to your computer and use it in GitHub Desktop.
Save puffnfresh/5096299 to your computer and use it in GitHub Desktop.
Implementing a Single Abstract Method from a Scala lambda using macros (SAMBDAS!)
import MyFuncMacro.myfunc
object MyFuncExample {
def main(args: Array[String]) {
val x: MyFunc[Int, Int] = myfunc { a: Int => a }
println(x)
println(x(42))
}
}
import language.experimental.macros
import reflect.macros.Context
trait MyFunc[-A, +B] {
def apply(a: A): B
}
object MyFuncMacro {
def myfunc[A, B](f: A => B) = macro myfuncImpl[A, B]
def myfuncImpl[A: c.WeakTypeTag, B: c.WeakTypeTag](c: Context)(f: c.Expr[A => B]) =
c.universe.reify {
new MyFunc[A, B] {
def apply(a: A) = f.splice.apply(a)
}
}
}
@travisbrown
Copy link

I'm not sure the macro buys you anything here—unless I'm missing something, it's just a fancy way of writing this:

def myfunc[A, B](f: A => B) = new MyFunc[A, B] { def apply(a: A) = f.apply(a) }

You could write a macro that'd take apart the function literal expression and avoid the unnecessary Function1.apply altogether, though—see my revision here, for example.

It's not as pretty, and I'd have to add an extra case for non-function literal arguments to get exactly the same behavior as yours, but it has the advantage of removing one layer of wrapping when you're working with function literals.

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