Search code examples
javascalavert.xvertx-eventbus

Scala compilation error Vert.x response future


I'm trying to replicate a code from https://vertx.io/docs/vertx-core/scala/#_the_event_bus_api but I got a compile error.

override def start(): Unit = {
    vertx.eventBus.sendFuture("anAddress", "message 1").onComplete {
      case Success(result) => {
        println("The handler un-registration has reached all nodes")
      }
      case Failure(cause) => {
        println(s"$cause")
      }
    }
  }

I'm getting this error:

missing parameter type for expanded function
The argument types of an anonymous function must be fully known. (SLS 8.5)
Expected type was: scala.util.Try[io.vertx.scala.core.eventbus.Message[?]] => ?
    vertx.eventBus.sendFuture("anAddress", "message 1").onComplete {
                                                                   ^

How can I solve this?

I'm using Scala 2.12.8 and Vert.x 3.7.1

I have looked around but no sucess.

Thanks to advance!


Solution

  • Here's how to solve this:

    So vertx.eventBus.sendFuture returns a Future[Message[T]. Future's onComplete method takes a single parameter which is a funciton f: (Try[T]) => U.

    What you're doing there is you're using an anonymous function for which argument types must be fully declared.

    You need to specify the signature of your f signature.

    Two options I guess:

    1)

    vertx.eventBus.sendFuture("anAddress", "message 1").onComplete { x: Try[Message[_]] =>
      x match {
        case Success(result) => {
          println("The handler un-registration has reached all nodes")
        }
        case Failure(cause) => {
          println(s"$cause")
        }
      }
    }
    

    2)

    // define f
    def f(x: Try[Message[_]]) = x match {
      case Success(result) => {
        println("The handler un-registration has reached all nodes")
      }
      case Failure(cause) => {
        println(s"$cause")
      }
    }
    
    // and later use it
    vertx.eventBus.sendFuture("anAddress", "message 1").onComplete(f)
    

    === LITTLE EDIT TO ADD SIMPLE EXPLANATION ==

    Have a look at the attached image:

    enter image description here

    The code in red is actually the body of a function that does not have a name (anonymous) for which the compiler needs to know the signature (its parameters and the type of them).

    So doing .onComplete { ... or .onComplete(f) is the same but if you define f elsewhere you've already defined its signature. If not, you need to do it like this .onComplete { x: Try[Message[_]] => ....

    (Little reminder: in Scala you can define functions like this val double = (i: Int) => { i * 2 })