This page is no longer maintained — Please continue to the home page at www.scala-lang.org

Scala Actors avoiding type-safety?

2 replies
Joshua.Suereth
Joined: 2008-09-02,
User offline. Last seen 32 weeks 5 days ago.
I noticed a lot of interesting things in scala actors trunk, like CanReply.   I love the idea of where this is going so I decided to try it out.   However, it looks like there's an issue with trying to do a typed override that hoses up the type system on the library, actively preventing me from attempting type safety.
Here's an example:
scala> class MyActor extends Actor with InputChannel[MyMessage] {     |   def act() = Actor.loop {     |     react {      |        case x => println(x)      |     }     |   }     | }<console>:12: error: missing parameter type for expanded functionThe argument types of an anonymous function must be fully known. (SLS 8.5) Expected type was: ?           react {                 ^
vs.
scala> class MyActor extends Actor {     |   def act() = Actor.loop {      |    react { case x => println(x) }     |   }     | }defined class MyActor


It seems to me that the type (Actor extends InputChannel[Any]) with InputChannel[MyMessage] should either choose to be an InputChannel[Any] or an InputChannel[MyMessage] based on variance.
I was hoping that I could make the internal API (react, receive, reactWIthin) be type safe and gain the sealed trait safety mechanisms in pattern matches.   However, it appears this does nothing useful right now.
As another aside, the InputChannel[+Msg] trait appears to only use the Msg class in a few of its methods, not all of them.   This gives me the false security of a type-safe interface because I can't actually use receiveWithin and get type safety with InputChannel (it accepts Any).  Is that a overlooked portion of the API or is there some other reason that it can't be made to use the Msg type parameter?

- Josh
Philipp Haller
Joined: 2009-01-13,
User offline. Last seen 42 years 45 weeks ago.
Re: Scala Actors avoiding type-safety?
Hi Josh,
On Mar 14, 2011, at 1:26 AM, Josh Suereth wrote:
It seems to me that the type (Actor extends InputChannel[Any]) with InputChannel[MyMessage] should either choose to be an InputChannel[Any] or an InputChannel[MyMessage] based on variance.

Basically, you are trying to override methods of `Actor` with methods of `InputChannel[MyMessage]`. This fails, since `Actor` extends `InputChannel[Any]`:
test.scala:4: error: overriding method ? in trait InputChannel of type => String;  method ? in trait Actor of type => Any has incompatible type class MyActor extends Actor with InputChannel[String]       ^ one error found
Since `Msg` in `InputChannel[+Msg]` is covariant, `InputChannel[MyMessage] <: InputChannel[Any]`. Therefore, one might want to conclude that `(Actor extends InputChannel[Any]) with InputChannel[MyMessage] <: InputChannel[MyMessage]`.

As another aside, the InputChannel[+Msg] trait appears to only use the Msg class in a few of its methods, not all of them.   This gives me the false security of a type-safe interface because I can't actually use receiveWithin and get type safety with InputChannel (it accepts Any).  Is that a overlooked portion of the API or is there some other reason that it can't be made to use the Msg type parameter?

The only methods in the `InputChannel[+Msg]` trait that don't use the `Msg` type are `receiveWithin` and `reactWithin`. And the reason why is that there it must be possible to pass partial functions which are defined at `TIMEOUT` (an object in `scala.actors`). Since it is not possible to constrain `Msg` to be "any type union the singleton type that includes `TIMEOUT`" these methods take a `PartialFunction[Any, R]` or `PartialFunction[Any, Unit]`, respectively, as arguments.
Cheers, Philipp
Joshua.Suereth
Joined: 2008-09-02,
User offline. Last seen 32 weeks 5 days ago.
Re: Scala Actors avoiding type-safety?

So... If i wanted thwarting compiler to warn me of unhandled messages, id want

this.asInstanceOf[InputChannel[MyMessageType].react {
  case  ....
}

?

On Mar 14, 2011 6:32 PM, "Philipp Haller" <philipp.haller@epfl.ch> wrote:

Hi Josh,

On Mar 14, 2011, at 1:26 AM, Josh Suereth wrote:
>
> It seems to me that the type (Actor extends Inp...

Basically, you are trying to override methods of `Actor` with methods of `InputChannel[MyMessage]`. This fails, since `Actor` extends `InputChannel[Any]`:
test.scala:4: error: overriding method ? in trait InputChannel of type => String;  method ? in trait Actor of type => Any has incompatible type class MyActor extends Actor with InputChannel[String]       ^ one error found
Since `Msg` in `InputChannel[+Msg]` is covariant, `InputChannel[MyMessage] <: InputChannel[Any]`. Therefore, one might want to conclude that `(Actor extends InputChannel[Any]) with InputChannel[MyMessage] <: InputChannel[MyMessage]`.

> As another aside, the InputChannel[+Msg] trait appears to only use the Msg class in a few of its m...

The only methods in the `InputChannel[+Msg]` trait that don't use the `Msg` type are `receiveWithin` and `reactWithin`. And the reason why is that there it must be possible to pass partial functions which are defined at `TIMEOUT` (an object in `scala.actors`). Since it is not possible to constrain `Msg` to be "any type union the singleton type that includes `TIMEOUT`" these methods take a `PartialFunction[Any, R]` or `PartialFunction[Any, Unit]`, respectively, as arguments.
Cheers, Philipp

Copyright © 2012 École Polytechnique Fédérale de Lausanne (EPFL), Lausanne, Switzerland