Reference capabilities make it safe to both pass mutable data between actors and to share immutable data amongst actors. Not only that, they make it safe to do it with no copying, no locks, in fact, no runtime overhead at all.
For an object to be mutable, we need to be sure that no other actor can read from or write to that object. The three mutable reference capabilities (
ref) all make that guarantee.
But what if we want to pass a mutable object from one actor to another? To do that, we need to be sure that the actor that is sending the mutable object also gives up the ability to both read from and write to that object.
This is exactly what
iso does. It is read and write unique, there can only be one reference at a time that can be used for reading or writing. If you send an
iso object to another actor, you will be giving up the ability to read from or write to that object.
So I should use
iso when I want to pass a mutable object between actors? Yes! If you don’t need to pass it, you can just use
If you want to share an object amongst actors, then we have to make one of the following guarantees:
- Either no actor can write to the object, in which case any actor can read from it, or
- Only one actor can write to the object, in which case other actors can neither read from or write to the object.
The first guarantee is exactly what
val does. It is globally immutable, so we know that no actor can ever write to that object. As a result, you can freely send
val objects to other actors, without needing to give up the ability to read from that object.
So I should use
val when I want to share an immutable object amongst actors? Yes! If you don’t need to share it, you can just use
ref instead, or
box if you want it to be immutable.
The second guarantee is what
tag does. Not the part about only one actor writing (that’s guaranteed by any mutable reference capability), but the part about not being able to read from or write to an object. That means you can freely pass
tag objects to other actors, without needing to give up the ability to read from or write to that object.
What’s the point in sending a tag reference to another actor if it can’t then read or write the fields? Because
tag can be used to identify objects and sometimes that’s all you need. Also, if the object is an actor you can call behaviours on it even though you only have a
So I should use
tag when I want to share the identity of a mutable object amongst actors? Yes! Or, really, the identity of anything, whether it’s mutable, immutable, or even an actor.
Reference capabilities that can’t be sent
You may have noticed we didn’t mention
box as things you can send to other actors. That’s because you can’t do it. They don’t make the guarantees we need in order to be safe.
So when should you use those reference capabilities?
ref when you need to be able to change an object over time. On the other hand, if your program wouldn’t be any slower if you used an immutable type instead, you may want to use a
box when you don’t care whether the object is mutable or immutable. In other words, you want to be able to read it, but you don’t need to write to it or share it with other actors.
trn when you want to be able to change an object for a while, but you also want to be able to make it globally immutable later.