Philipp Haller wrote:
> First, why are actors currently untyped?
> Originally, the actors library emerged from an experiment to implement
> Erlang in Scala. In that model, it is common to have nested receives, i.e.
>
> receive {
> case first =>
> ...
> receive {
> case second => ...
> }
> }
>
> Now, if the types of `first` and `second` are unrelated, then certainly
> the actor must be able to accept messages of type `Any`. Otherwise, at
> least one of the receives would block indefinitely which is undesirable.
So, in this case you create an Actor[Any] (or a more advanced type with
Either or the message sequence encoded in the type). I can't think of
any reason why the Actor class shouldn't have a type parameter.
> Why does this "untyped" scheme work surprisingly well in Scala? Pattern
> matching helps you recover types, e.g.:
>
> case class DoThis(x: List[(Int, String)])
> receive {
> case DoThis(args) => // know that args: List[(Int, String)]
> }
The usefulness of message type check is not primarily on the receiver
side, it's on the caller side. You don't want to send a message of
incorrect type to an actor and get a runtime error.
In essence, you can view an actor as a function of type "A =>
Future[B]". Types A and B are clearly related, if you send an actor a
certain message type you would expect a reply of a certain type. How can
we encode this in Scala? The straightforward way would be to encode the
return type in the message type, for example:
trait Message { type ReturnType }
case class MyMess(x : Int, y : Int) extends Message {
type ReturnType = Int
}
trait Actor[Msg] {
def ! : Future[T#ReturnType]
}
(alternatively "trait Actor[Msg <: Message]")
However, implementing the receive method in a type safe way is AFAIK not
possible to do in Scala, you would have to resort to casting.
/Jesper Nordenberg