3

I'm implementing an actor-based app in scala and I'm trying to be able to pass functions between the actors for them to be processed only when some message is received by the actor.

import actors.Actor
import java.util.Random

import scala.Numeric._
import Implicits._

class Constant(val n:Number) extends Actor{
    def act(){
        loop{
            receive{
                case "value" => reply( {n} )
            }
        }
    }
}

class Arithmetic[T: Numeric](A: ()=>T, B: ()=>T) extends Actor{
  def act(){
    receive{
      case "sum" => reply ( A() + B() )

    /*  case "mul" => reply ( A * B )
    */
    }
  }
}

object Main extends App{
    val c5 = new Constant(5)
    c5.start


    val a = new Arithmetic({c5 !! "value"}, {c5!!"value"} )
  a.start

  println(a!?"sum")
  println(a!?"mul")

}

In the example code above I would expect the output to be both 5+5 and 5*5. The issue is that reply is not a typed function and as such I'm unable to have the operator (+,*) to operate over the result from A and B.

Can you provide any help on how to better design/implement such system?

Edit: Code updated to better reflect the problem. Error in: error: could not find implicit value for evidence parameter of type Numeric[Any] val a = new Arithmetic({c5 !! "value"}, {c5!!"value"} )

I need to be able to pass the function to be evaluated in the actor whenever I call it. This example uses static values but I'll bu using dynamic values in the future, so, passing the value won't solve the problem. Also, I would like to receive different var types (Int/Long/Double) and still be able to use the same code.

tiagoboldt
  • 2,426
  • 1
  • 24
  • 30

2 Answers2

1

The error: Error in: error: could not find implicit value for evidence parameter of type Numeric[Any]. The definition of !!:

def !! (msg: Any): Future[Any]

So the T that Arithmetic is getting is Any. There truly isn't a Numeric[Any].

Daniel C. Sobral
  • 295,120
  • 86
  • 501
  • 681
  • I understand the error. I don't understand how I can refactor the code so that I'm able to do what I want to. Any hint would be appreciated. – tiagoboldt Oct 12 '11 at 23:01
  • 1
    @tiagoboldt Well, first of all, `Numeric` has to be passed all along the chain -- meaning `Constant` has to receive it, and pass it on the reply. Next, once you get it back from `Constant`, you'll need to pass it to `Arithmetic`, and there's the slight matter of ensuring it is the same `Numeric` for both parameters. So, in short, give up `!!` and write code in terms of actors messaging each other. – Daniel C. Sobral Oct 12 '11 at 23:07
0

I'm pretty sure that is not your problem. First, A and B are functions, and functions don't have + or *. If you called A() and B(), then you might stand a chance... except for the fact that they are java.lang.Number, which also does not have + or * (or any other method you'd expect it to have).

Basically, there's no "Number" type that is a superclass or interface of all numbers for the simple reason that Java doesn't have it. There's a lot of questions touching this subject on Stack Overflow, including some of my own very first questions about Scala -- investigate scala.math.Numeric, which is the best approximation for the moment.

Method vs Function and lack of parenthesis

Methods and functions are different things -- see tons of related questions here, and the rule regarding dropping parenthesis is different as well. I'll let REPL speak for me:

scala> def f: () => Int = () => 5
f: () => Int

scala> def g(): Int = 5
g: ()Int

scala> f
res2: () => Int = <function0>

scala> f()
res3: Int = 5

scala> g
res4: Int = 5

scala> g()
res5: Int = 5
Community
  • 1
  • 1
Daniel C. Sobral
  • 295,120
  • 86
  • 501
  • 681
  • Hi, 1st, when calling a function in scala, there's no need to use the () if there are no parameters, so, writing A is evaluated and typed to what A() would be. I've also already tried using numeric but had no luck with it. Any code/design refactor to hint on the problem would be much appreciated. – tiagoboldt Oct 12 '11 at 21:08
  • @tiagoboldt When calling a *method* there is no such need. When calling a function, there is. – Daniel C. Sobral Oct 12 '11 at 21:10
  • I've edited my question to make it clearer. You're right on the above, but that's not my question. Hope It's clearer now. – tiagoboldt Oct 12 '11 at 22:39