This is kind of an opinion piece but I’ve been programming canisters for around a year now.
I’ve programmed a multi canister backend with Motoko and things mostly work. The actor model is mostly embraced there.
I’m currently programming another backend with Rust and believe it is, as of today, a superior language owing to the amount of control and safety it provides. While still providing the nice productivity abstractions you expect out of a modern language. Provided you are willing to put in the time and patience to learn it.
Both these backends are multi canisters which is where the actor paradigm is supposed to shine.
Quoting Wikipedia, an actor is defined as:
An actor is a computational entity that, in response to a message it receives, can concurrently:
- send a finite number of messages to other actors;
- create a finite number of new actors;
- designate the behavior to be used for the next message it receives.
Looking at Rust,
send a finite number of messages to other actors
This is basically inter-canister calls on the IC. There are 2 ways for this:
- Using the
import
macro - this is broken right now - Using the
ic_cdk::api::call::call
- This mostly works but is severely undocumented and has weird quirks like even single response values have to be tuples
Secondly,
create a finite number of new actors
This is the ability to spawn new canisters by a canister. Currently we have to figure out an esoteric way of doing this which is sorta undocumented. This leads to around a 100 lines of boilerplate code that calls into the management canister and does some plumbing to give you back your canister. Motoko has a concept of actor class
that Rust is missing. Rust needs an alternative of some kind that makes this API friendly.
There is also no prescribed method on how to manage these actors once they have been spawned with no guidance on how to perform upgrades or migrations. Which is a huge roadblock for adoption of multi canister backends.
Finally,
designate the behavior to be used for the next message it receives
This is basically the public methods that the canister exposes and these work as you would expect them to. No major complaints here.
As an aside, we also need better authorization primitives to be better able to gate who is allowed to execute what when calling into actors
Without the seamless availability of actors, it will be a struggle to build composable systems consisting of a fleet of actors talking to each other
P.S. Although the above reads like a rant, it is also a wish-list for things that should improve. I’m just a humble community member who only wishes to see the IC succeed.