Actors are object-orientation done right (as opposed to say, objects in Java): their state is not visible from the outside and they communicate via messages. There’s no way to break encapsulation because you can’t peek into an actor’s state while it is running. That’s the entire point of actors: they provide you with the illusion of a safe space in which things are executed sequentially, one message after the other, allowing you to use mutable state inside of your actor without having to worry about race conditions (well, almost: don’t leak the state).

Which is why using actors that don’t have state is somewhat odd, to say the least. With the exception of actors that handle supervision for larger parts of your actor system hierarchy (setting up back-off supervisors, for example), actors are really meant to deal with long-lasting computation that holds state. With long-lasting I mean to say that the actor will have multiple interactions in its lifetime, producing different results depending on its state, as opposed to one-shot computations. For those, Futures are an excellent abstraction: they allow asynchronous code exection, ideal for cases of network and disk related computation (or really intensive CPU tasks), are composable and have a failure-handling mechanism. They also integrate well with Akka actors (using the pipe pattern).

So: don’t use actors if you don’t have state - that’s not what they’re meant for.

Thanks to Heiko for the discussion on this topic in the cab to that fancy vegan restaurant during the last Scala Days in Berlin