Implicit ExecutionContext in traits - scala

I would like to have an implicit ExecutionContext passed to a partially implemented trait.
In code example:
import scala.concurrent.Future
trait Processor[T,R] {
def process(op:T): Future[R] = {
//Do something to get stuff from abstract methods
Future {
//Do something that returns type R
}
}
}
This will ask for an ExecutionContext, so I have changed the declaration to:
import scala.concurrent.Future
import scala.concurrent.ExecutionContext
trait Processor[T,R] {
def process(op:T)(implicit executor: ExecutionContext): Future[R] = {
//Do something to get stuff from abstract methods
Future {
//Do something that returns type R
}
}
}
But then when I try to extend the trait like this:
import scala.concurrent.ExecutionContext.Implicits.global
class StringProcessor extends Processor[String,String] {
//Bla bla bla
}
The compiler tells me that the method process is not implemented an my class should be abstract.
How can I ensure that my construct works without having to put an implicit val xc:ExecutionContext in the declaration of the trait?

I don't seem to be having any issues with the following code, which is similar to your code but provides a full implementation. Not sure what the issue is.
import scala.concurrent.Future
import scala.concurrent.ExecutionContext
trait Processor[T,R] {
def process(op:T)(implicit executor: ExecutionContext): Future[R] = {
//Do something to get stuff from abstract methods
Future {
getR
}
}
def getR:R
}
class StringProcessor extends Processor[String,String] {
def getR = "foo"
}

Related

Is there a straightforward and general way to wrap a scala object's code with code to be executed before and after the object body code?

I am trying to create some general functionality which allows me to add code to be executed before and after the body of a Scala object (extended with the App trait) in a generic way - something akin to Scalatest's BeforeAndAfterAll but for general code execution.
I would love to figure out a way to do this via a trait but am coming up short - something like
trait MyBeforeAndAfter {
def before = println("I am executed before!")
def after = println("I am executed after!")
}
object MyApp extends App with MyBeforeAndAfter {
println("I am generic code in the body that's wrapped")
}
and the target output when running the App would be (key feature being the ordering):
I am executed before
I am generic code in the body that's wrapped
I am executed after
Two approaches I have considered but can't figure out how to do are:
Somehow pass the code in the object body to a function which takes care of the wrapping - but I don't know how I can get access to the code block as something which I could pass to a function. I have looked at both the App trait itself and Scalatest's BeforeAndAfterAll to see their approaches. The former appears to be controlled in the compiler. The latter, I'm in the fifth level of inception and it's not yet clear to me how it works.
Split the before and after into separate traits and mix them in, and while trait ordering is pretty straightforward, I don't see any way to annotate that a trait should be executed after the base / target object / class.
Gods of Stack Overflow... help?
Edit per Luis' question - basically why do you want to do this?
I was working with akka quite a bit to build recently and with akka there's a lot of ActorSystem setup / teardown boilerplate - grabbing things from configs, standing up the system etc and I was thinking of ways to clear out some of that boilerplate to make the unique parts of the main app more visible. I ran into some similar desires in some other contexts as well and I continued to think about whether there was a general way to clear out the boilerplate in a "clean" manner - meaning similar to the App trait (no overrides required, just mixin and go), but also enabling flexibility to execute code both before and after the block.
Standard approach would be to run the code not in the body of an object but in some method
trait MyBeforeAndAfter {
def before() = println("I am executed before!")
def after() = println("I am executed after!")
def run(): Unit
def main(args: Array[String]): Unit = {
before()
run()
after()
}
}
object MyApp extends MyBeforeAndAfter {
override def run(): Unit = {
println("I am generic code in the body that's wrapped")
}
}
Then if you run MyApp it will print
I am executed before!
I am generic code in the body that's wrapped
I am executed after!
If you really want to run code in the body of an object you can define macro annotation
import scala.annotation.StaticAnnotation
import scala.language.experimental.macros
import scala.reflect.macros.blackbox
class beforeAndAfter extends StaticAnnotation {
def macroTransform(annottees: Any*): Any = macro BeforeAndAfterMacro.impl
}
object BeforeAndAfterMacro {
def impl(c: blackbox.Context)(annottees: c.Tree*): c.Tree = {
import c.universe._
annottees match {
case q"$mods object $tname extends { ..$earlydefns } with ..$parents { $self => ..$body }" :: Nil =>
val parents1 = parents :+ tq"MyBeforeAndAfter"
q"""$mods object $tname extends { ..$earlydefns } with ..$parents1 { $self =>
def run(): Unit = {
..$body
}
}"""
case _ =>
c.abort(c.enclosingPosition, "annottee must be an object")
}
}
}
#beforeAndAfter
object MyApp {
println("I am generic code in the body that's wrapped")
}
//Warning:scalac: object MyApp extends scala.AnyRef with MyBeforeAndAfter {
// def <init>() = {
// super.<init>();
// ()
// };
// def run(): Unit = println("I am generic code in the body that\'s wrapped")
//}
Here a similar approach from the of #DmytroMitin
The only difference is that this lets you customize and reuse before and foreach methods.
trait BeforeAndAfter {
def before(): Unit
def after(): Unit
}
trait Program { self: BeforeAndAfter =>
def run(args: List[String]): Unit
final def main(args: Array[String]): Unit = {
self.before()
run(args.toList)
self.after()
}
}
Which you can use like this:
trait MyBeforeAndAfter extends BeforeAndAfter {
override final def before(): Unit = {
println("Setup")
}
override final def after(): Unit = {
println("Clean up")
}
}
object MyApp extends Program with MyBeforeAndAfter {
override final def run(args: List[String]): Unit = {
println("Program")
}
}
You can see it running here.
You should use before and after as functions and then invoke them in the execute method. The execute method is taking custom function as input, and executes in certain order. This is a standard approach which works irrespective of whether you call it in main or in another class.
trait BeforeAfter {
def execute(myfunction : () => Unit) = {
before()
myfunction()
after()
}
def before() = println("before")
def after() = println("after")
}
object MyApp extends App with BeforeAfter{
def myprinter() = println("printing main")
execute(myprinter)
}
Results:
before
printing main
after

How to define a trait so that we extend with classes that have context bounds?

Suppose I want to be able to do:
trait MyTrait[T: Numeric] {
val numeric = implicitly[Numeric[T]]
import numeric.mkNumericOps
// more code
}
Then extend with
class MyClass[T: Numeric] extends MyTrait[T] {
// code
}
You get ye old "traits cannot have type parameters with context bounds".
Is there something that is syntactically very close to this, and does the same thing?
Like this:
trait MyTrait[T] {
val numeric: Numeric[T]
import numeric.mkNumericOps
// more code
}
class MyClass[T: Numeric] extends MyTrait[T] {
val numeric = implicitly[Numeric[T]]
// code
}

Scala: Multiple implicit conversions with same name

Using scala 2.10.3, my goal is to make the following work:
object A {
implicit class Imp(i: Int) {
def myPrint() {
println(i)
}
}
}
object B {
implicit class Imp(i: String) {
def myPrint() {
println(i)
}
}
}
import A._
import B._
object MyApp extends App {
3.myPrint()
}
This fails with
value myPrint is not a member of Int
If I give A.Imp and B.Imp different names (for example A.Imp1 and B.Imp2), it works.
Diving a bit deeper into it, there seems to be the same problem with implicit conversions.
This works:
object A {
implicit def Imp(i: Int) = new {
def myPrint() {
println(i)
}
}
implicit def Imp(i: String) = new {
def myPrint() {
println(i)
}
}
}
import A._
object MyApp extends App {
3.myPrint()
}
Whereas this doesn't:
object A {
implicit def Imp(i: Int) = new {
def myPrint() {
println(i)
}
}
}
object B {
implicit def Imp(i: String) = new {
def myPrint() {
println(i)
}
}
}
import A._
import B._
object MyApp extends App {
3.myPrint()
}
Why? Is this a bug in the scala compiler? I need this scenario, since my objects A and B derive from the same trait (with a type parameter) which then defines the implicit conversion for its type parameter. In this trait, I can only give one name for the implicit conversion. I want to be able to import more of these objects into my scope. Is there a way to do that?
edit: I can't give the implicit classes different names, since the examples above are only breaking down the problem. My actual code looks more like
trait P[T] {
implicit class Imp(i: T) {
def myPrint() {
...
}
}
}
object A extends P[Int]
object B extends P[String]
import A._
import B._
The implicits just have to be available as a simple name, so you can rename on import.
Just to verify:
scala> import A._ ; import B.{ Imp => BImp, _ }
import A._
import B.{Imp=>BImp, _}
scala> 3.myPrint
3
Actually, it works if you replace
import A._
import B._
with
import B._
import A._
What happens, I think, is that A.Imp is shadowed by B.Imp because it has the same name. Apparently shadowing applies on the function's name and do not take the signature into account.
So if you import A then B, then only B.Imp(i: String) will be available, and if you import B then A, then only A.Imp(i: Int) will be available.
If you need to use both A.Imp and B.Imp, you must rename one of them.
In case anyone else runs into this issue, there is a partial workaround, which I found here:
https://github.com/lihaoyi/scalatags/blob/3dea48c42c5581329e363d8c3f587c2c50d92f85/scalatags/shared/src/main/scala/scalatags/generic/Bundle.scala#L120
That code was written by Li Haoyi, so you can be pretty confident that no better solution exists...
Essentially, one can still use traits to define methods in terms of each other, but it will require boilerplate to copy those implicits into unique names. This example might be easier to follow:
trait Chainable
object Chainable {
implicit val _chainableFromInt = IntChainable.chainable _
implicit val _chainableFromIntTrav = IntChainable.traversable _
implicit val _chainableFromIntOpt = IntChainable.optional _
implicit val _chainableFromIntTry = IntChainable.tried _
implicit val _chainableFromDom = DomChainable.chainable _
implicit val _chainableFromDomTrav = DomChainable.traversable _
implicit val _chainableFromDomOpt = DomChainable.optional _
implicit val _chainableFromDomTry = DomChainable.tried _
private object IntChainable extends ImplChainables[Int] {
def chainable(n:Int) = Constant(n)
}
private object DomChainable extends ImplChainables[dom.Element]{
def chainable(e:Element) = Insertion(e)
}
private trait ImplChainables[T] {
def chainable(t:T):Chainable
def traversable(trav:TraversableOnce[T]):Chainable =
SeqChainable(trav.map(chainable).toList)
def optional(opt:Option[T]):Chainable =
opt match {
case Some(t) => chainable(t)
case None => NoneChainable
}
def tried(tried:Try[T]):Chainable =
optional(tried.toOption)
}
}
In other words, never write:
trait P[T] {
implicit def foo(i: T) = ...
}
object A extends P[X]
Because defining implicits in type parameterized traits will lead to these naming conflicts. Although, incidentally, the trait in mentioned in the link above is parameterized over many types, but idea there is that none of the implementations of that trait are ever needed in the same scope. (JSDom vs Text, and all._ vs short._ for those familiar with Scalatags)
I also recommend reading: http://www.lihaoyi.com/post/ImplicitDesignPatternsinScala.html
It does not address this issue specifically but is an excellent summary of how to use implicits.
However, putting all these pieces together, this still seems to be an issue:
trait ImplChainables[AnotherTypeClass]{
type F[A] = A=>AnotherTypeClass
implicit def transitiveImplicit[A:F](t: A):Chainable
implicit def traversable[A:F](trav: TraversableOnce[A]):Chainable = ...
}
What this trait would allow is:
object anotherImpl extends ImplChainables[AnotherTypeClass] {...}
import anotherImpl._
implicit val string2another: String=>AnotherTypeClass = ...
Seq("x"):Chainable
Because of the type parameter and the context binding (implicit parameter) those cannot be eta-expanded (i.e: Foo.bar _ ) into function values. The implicit parameter part has been fixed in Dotty: http://dotty.epfl.ch/blog/2016/12/05/implicit-function-types.html
I do not know if a complete solution would be possible, needless to say this is a complex problem. So it would be nice if same name implicits just worked and the whole issue could be avoided. And in any case, adding an unimport keyword would make so much more sense than turning off implicits by shadowing them.

Implicit parameter resolution from surrounding scope

I'm not a fan of bringing implicit parameters into my code so where I use them I want to encapsulate their use. So I am trying to define an object that both wraps up calls to spray-json with exception handling and contains default implicit JsonFormats for each of my model classes. However the implicit parameters are not resolved unless they are imported into the client, calling code, which is exactly where I don't want them to be. Here's what I have so far (which doesn't resolve the implicit formatters), is there a way I can get what I want to work?
package com.rsslldnphy.json
import com.rsslldnphy.models._
import spray.json._
object Json extends DefaultJsonProtocol {
implicit val personFormat = jsonFormat1(Person)
implicit val animalFormat = jsonFormat1(Animal)
def parse[T](s:String)(implicit reader: JsonReader[T]): Option[T] = {
try { Some(JsonParser(s).convertTo[T]) }
catch { case e: DeserializationException => None }
}
}
NB. a JsonFormat is a type of JsonReader
EDIT: Here's what I've written based on #paradigmatic's second suggestion (which I can't get to work, I still get Cannot find JsonReader or JsonFormat type class for T). Am I missing something?
object Protocols extends DefaultJsonProtocol {
implicit val personFormat = jsonFormat1(Person)
implicit val animalFormat = jsonFormat1(Animal)
}
object Json {
def parse[T](s:String): Option[T] = {
import Protocols._
try { Some(JsonParser(s).convertTo[T]) }
catch { case e: DeserializationException => None }
}
}
For the record, this is a code snippet that does work, but that I'm trying to avoid as it requires too much of the client code (ie. it needs to have the implicits in scope):
object Json extends DefaultJsonProtocol {
implicit val personFormat = jsonFormat1(Person)
implicit val animalFormat = jsonFormat1(Animal)
}
object ClientCode {
import Json._
def person(s: String): Person = JsonParser(s).convertTo[Person]
}
You could declare the implicits in the companion objects:
object Person {
implicit val personFormat: JReader[Person] = jsonFormat1(Person)
}
object Animal {
implicit val animalFormat: JReader[Animal] = jsonFormat1(Animal)
}
The implicit resolution rules are very complex. You can find more information in this blog post. But if the compiler is looking for a typeclass T[A], it will look (soon or later) for it in the companion object of class/trait A.
EDIT: If the issue is only a problem of scope "pollution", you could just introduce some braces. With your code example, you could call the function parse as:
package com.rsslldnphy.json
import com.rsslldnphy.models._
import spray.json._
object Json extends DefaultJsonProtocol {
implicit val personFormat = jsonFormat1(Person)
implicit val animalFormat = jsonFormat1(Animal)
def parse[T](s:String)(implicit reader: JsonReader[T]): Option[T] = {
try { Some(JsonParser(s).convertTo[T]) }
catch { case e: DeserializationException => None }
}
}
object JsonFacade {
def optParse[T]( s: String ): Option[T] = {
import Json._
parse[T]( s )
}
}
Here the implicits "pollutes" only the optParse method.

Access to ExecutionContext

I have this trait
trait NonBlockingGoodness extends DataStore {
import akka.dispatch.{ Future, ExecutionContext }
import akka.util.duration._
import akka.util.Timeout
implicit val ec = ExecutionContext.fromExecutorService(yourExecutorServiceGoesHere)
implicit lazy val timeout = Timeout(5 seconds)
}
I would like to access the ExecutionContext in another trait like such
trait AsyncGoodness extends NonBlockingGoodness {
import akka.dispatch.Future
def doSomething = {
Future { "Future is the bomb." }
}
However, I am getting the error
Could not find implicit value for parameter executor: akka.dispatch.ExecutionContext
UPDATED:
I figured out how to get the ExecutionContext in scope
trait AsyncGoodness extends NonBlockingGoodness {
import akka.dispatch.ExecutionContext
import akka.dispatch.Future
def doSomething()(implicit executor: ExecutionContext) = {
Future { "Future is the bomb." }
}
However, I have a follow-up question. Since I may have more than 1 method in AsyncGoodness that uses ExecutionContext, is there a way to pass it in at the trait level instead of at each method like I did above.
I know you'd rather not have to import anything extra, but something like this should work for you.
trait NonBlockingGoodness {
import scala.concurrent.{ Future, ExecutionContext }
import scala.concurrent.util.duration._
import akka.util.Timeout
object Implicit {
implicit val ec = ExecutionContext.Implicits.global
implicit lazy val timeout = Timeout(5 seconds)
}
}
trait AsyncGoodness extends NonBlockingGoodness {
import scala.concurrent.Future
import Implicit._
def doSomething = {
Future { "Future is the bomb." }
}
}
As it turns out, all I need to do is explicitly specify ec return type for the compiler to use it. Here's the working code
trait NonBlockingGoodness extends DataStore {
import akka.dispatch.{ Future, ExecutionContext }
import akka.util.duration._
import akka.util.Timeout
implicit val ec: ExecutionContext = ExecutionContext.fromExecutorService(yourExecutorServiceGoesHere)
implicit lazy val timeout = Timeout(5 seconds)
}
trait AsyncGoodness extends NonBlockingGoodness {
import akka.dispatch.Future
def doSomething = {
Future { "Future is the bomb." }
}