scala/scala-async

await as an extension method

NazneenRupawalla opened this issue · 6 comments

Can we have await as an extension method, a la apply in Akka Dataflow? This could make some code a bit nicer to read and write.

Just to clarify, we can not currently add say "!" as an extension method (using implicit class) which delegates to library await. This is because it must be used within async block. If this was allowed, we could very easily migrate from dataflow to this library.

I believe you could do this if your extension method itself was a macro that expanded to an await call. The async macro won't know the difference!

Really struggling to create it as an extension method as macro. Can you help with a sample gist please?

Sure:

scala> import language.experimental.macros, reflect.macros.Context
import language.experimental.macros
import reflect.macros.Context

scala> def impl(c: Context) = { import c.universe._; q"_root_.scala.async.Async.await(${c.prefix.tree.asInstanceOf[Apply].args.head})" }
warning: there were 1 deprecation warning(s); re-run with -deprecation for details
impl: (c: reflect.macros.Context)c.universe.Tree

scala> implicit class RichAny[T](t: concurrent.Future[T]) { def ! : T = macro impl }
defined class RichAny

scala> import scala.concurrent.ExecutionContext.Implicits.global
import scala.concurrent.ExecutionContext.Implicits.global

scala> def f = concurrent.Future(42)
f: scala.concurrent.Future[Int]

scala> import scala.async.Async.{async, await}
import scala.async.Async.{async, await}
scala> async(f.!)
res6: scala.concurrent.Future[Int] = scala.concurrent.impl.Promise$DefaultPromise@34e2e28d

The non-obvious part is using Context#prefix to access the tree representing the implicit application: RichAny(f) in order to get a hold of the tree f.

Works! No way I was going to figure out c.prefix thingy on my own :)

Thank you so much.

On Fri, Oct 17, 2014 at 11:51 AM, Jason Zaugg notifications@github.com
wrote:

The non-obvious part is using Context#prefix to access the tree
representing the implicit application: RichAny(f) in order to get a hold
of the tree f.


Reply to this email directly or view it on GitHub
#88 (comment).