Extermely unfortunate collision between scalaz and Akka libraries "!"

66 views
Skip to first unread message

Chris Marshall

unread,
Jun 28, 2011, 6:31:16 AM6/28/11
to sca...@googlegroups.com, akka...@googlegroups.com
The akka message-send method is declared on ScalaActorRef as follows:

def !(message : scala.Any)(implicit sender : scala.Option[akka.actor.ActorRef]

The fact that this takes an implicit parameter seems to be a killer, when a Scalaz import is in scope. Consider the following program:

object AkkaTest {
  def main(args: Array[String]) {
    class MyActor extends akka.actor.Actor {
      protected def receive = {case any => println("Hello : " + any)}
    }

    val a = akka.actor.Actor.actorOf(new MyActor) //returns ActorRef, not ScalaActorRef
    a.start()
//    import scalaz._
//    import Scalaz._

    println( a ! 'foo )
  }
}

It compiles. If you uncomment the scalaz imports, the compiler complains that 'foo is not an Int. This is presumably because the compiler is resolving the ! call as a call to scalaz.MA.! as opposed to using the implicit conversion from ActorRef to ScalaActorRef in the package object akka.actor (http://akka.io/api/akka/1.1.2/#akka.actor.package).

Obviously the answer is to "force" scalac to invoke the akka conversion via an explicit type hint "akka.actor.Actor.actorOf(new MyActor) : ScalaActorRef".

I just thought I'd bring this to your attention (in case it had not before), and to see whether anyone had any nicer ways of avoiding it

Chris


Roland Kuhn

unread,
Jun 28, 2011, 4:35:45 PM6/28/11
to akka...@googlegroups.com, sca...@googlegroups.com
I’m guessing that the ScalaActorRef is used to hide the scala-only methods link $bang from Java users, which is a valid reason in my opinion. On the other hand, the rather broad conversion provided by the scalaz standard import seems … questionable (if I interpret your mail correctly: I was not able to identify the exact implicit method which pimps the ActorRef into an MA).

But: I don’t see any reason to panic!

I tried to reproduce with a mock REPL session, but couldn’t reproduce the failure:

scala> implicit def toMult(x: Any) = new { def !(y: Int)(implicit x:Int) = x.toString * y }
toMult: (x: Any)java.lang.Object{def !(y: Int)(implicit x: Int): String}

scala> implicit def toString(s: String) = new { def !(a: Any)(implicit s:String = "buh") {println(s)} }
toString: (s: String)java.lang.Object{def !(a: Any)(implicit s: String): Unit; def !$default$2(a: Any): String @scala.annotation.unchecked.uncheckedVariance}

scala> "hello" ! "buh"
buh

scala> implicit val x = 42
x: Int = 42

scala> 12 ! 3
res8: String = 424242

scala> "hello" ! 3
buh

scala> println("hello" ! 3)
buh
()

So, unless you want the Scalaz ! on an ActorRef, it looks fine from this perspective. And you sample code suggests that the compilation failure occurs when trying to print the result of an actor’s ! method, which does not make much sense anyway. Or do you see it also in a non-Unit context?

Regards,

Roland

--
You received this message because you are subscribed to the Google Groups "Akka User List" group.
To post to this group, send email to akka...@googlegroups.com.
To unsubscribe from this group, send email to akka-user+...@googlegroups.com.
For more options, visit this group at http://groups.google.com/group/akka-user?hl=en.

Chris Marshall

unread,
Jun 29, 2011, 6:28:57 AM6/29/11
to sca...@googlegroups.com
The Scalaz._ import is something that you basically *have* to do, because this brings all the implicit typeclass instances into view. The implicit being resolved is a conversion to an MA in MAsLow.maImplicit.

I couldn't reproduce the failure in the REPL either, I meant to say that. I don't know enough about the REPL to understand why this is happening and whether it should be classes as a bug - but the code I posted definitely does *not* compile under scalac

Chris

You received this message because you are subscribed to the Google Groups "scalaz" group.
To post to this group, send email to sca...@googlegroups.com.
To unsubscribe from this group, send email to scalaz+un...@googlegroups.com.
For more options, visit this group at http://groups.google.com/group/scalaz?hl=en.

Jason Zaugg

unread,
Jun 29, 2011, 7:21:14 AM6/29/11
to sca...@googlegroups.com
On Wed, Jun 29, 2011 at 12:28 PM, Chris Marshall <oxbow...@gmail.com> wrote:
> The Scalaz._ import is something that you basically *have* to do, because
> this brings all the implicit typeclass instances into view. The implicit
> being resolved is a conversion to an MA in MAsLow.maImplicit.
> I couldn't reproduce the failure in the REPL either, I meant to say that. I
> don't know enough about the REPL to understand why this is happening and
> whether it should be classes as a bug - but the code I posted definitely
> does *not* compile under scalac

Actor Ref extends Comparable[ActorRef], which qualifies for maImplicit.

I can't think of a suitable workaround, other than restricting the
scope of your imports.

I definitely want to make the imports and pimped methods more
a-la-carte in Scalaz7, but it's not clear how that will be achieved.

-jason

Chris Marshall

unread,
Jun 29, 2011, 8:18:27 AM6/29/11
to sca...@googlegroups.com
To Akka - what is the thinking behind supplying an ordering on ActorRef (i.e. implementing Comparable)? Of what use is that?

Chris

Derek Williams

unread,
Jun 29, 2011, 8:38:48 AM6/29/11
to sca...@googlegroups.com, akka...@googlegroups.com
On Wed, Jun 29, 2011 at 6:18 AM, Chris Marshall <oxbow...@gmail.com> wrote:
> To Akka - what is the thinking behind supplying an ordering on ActorRef
> (i.e. implementing Comparable)? Of what use is that?
> Chris

I think it is for use in ordered collections, but I'm not sure where
it is actually used like that.

--
Derek

Reply all
Reply to author
Forward
0 new messages