Actor System Ergonomics Poll (axiom)

I am the author of the axiom crate and I am working on the 0.1.0 release and I am trying to firm up the ergonomics and final API. I have a question for the readers here. What mechanism would they feel is the most comfortable and ergonomic way to create an actor that may have special config options.

Question of ergonomics. If you are spawning an actor which methodology would you prefer?

// Option 1: Multiple Methods
system.spawn(my_state, my_handler_func);
system.spawn_named("foo", my_state, my_handler_func);
system.spawn_with(ActorConfig{ name: Some("foo"), channel_size: 100 } my_state, my_handler_func);

// Option 2; Builder but no default `spawn` on the system.
system.actor().spawn(my_state, my_handler_func);
system.actor().name("Foo").spawn(my_state, my_handler_func);
system.actor().name("Foo").channel_size(100).spawn(my_state, my_handler_func);

This is purely an ergonomics question. In the first options it saves you a chained call in the simple state but in the second option its more fluid and expandable.

Opinions are welcome.

The builder pattern is well known within Rust, so I would go with the second one. Option 2 is also easier to change, whereas Option 1 is kinda hard to modify. Also there is a combinatorial explosion when you scale up the number of parameters, so it is more future-proof to go with the builder pattern.

This can be managed with a config type, but that also locks you into a certain config. Because of this, you will need to make a new config type every time you want to add a field. The builder pattern neatly side-steps this by making fields private, and only accessible through the given methods.

2 Likes