Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Use Scala function instead of a Java callback-like anonymous object

Java-style anonymous callbacks include relatively much boilerplate and are not pleasing to read. It would be nice to have something like

workExpression

instead of

new SomeIF {
    @Override public someType doRun() {
        return workExpression
    }
}

What are the possible solutions?

like image 842
ron Avatar asked Mar 06 '26 17:03

ron


2 Answers

A possible solution is using implicit defs for converting functions to the legacy callback types. For example:

// Required by some API
trait Callable[A] {
  def call(): A
}

trait Processor[A,B] {
  def process(a: A): B
}

// Our helper trait
trait MyImplicits {
  implicit def funToCallable[A](f: () => A) = new Callable[A]() { 
    def call() = f()
  }

  implicit def funToProcessor[A,B](f: (A) => B) = new Processor[A,B]() {
    def process(a: A) = f(a)
  }

}

object App extends MyImplicits {

  def main(args: Array[String]) {
    // Traditional usage
    runSomeCallable(new Callable[String]() {
      def call() = "World"
    })

    runSomeProcessor(new Processor[String,Int] {
      def process(a: String) = a.toInt * 2
    })

    // Usage with implicits
    runSomeCallable(() => "Scala World")

    runSomeProcessor((s: String) => s.toInt * 2)
  }

  // Methods defined by some foreign API
  def runSomeCallable[A](callable: Callable[A]) {
    println("Hello "+callable.call())
  }

  def runSomeProcessor(processor: Processor[String,Int]) {
    println("From 1 to "+processor.process("1"))
  }

}

Therefore when working with some code, one could create a helper trait for the common callback types used in that code to ease readability.

like image 109
ron Avatar answered Mar 08 '26 06:03

ron


Automatic conversion of closures to interfaces with single methods may appear in a future version of Scala: http://www.scala-lang.org/node/8744 This would avoid the boilerplate with implicits which is currently necessary.

like image 25
Alexey Romanov Avatar answered Mar 08 '26 06:03

Alexey Romanov



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!