State machine DSL/library

Over the holidays, I published a state machine DSL that I’m using in-house on several projects. Came here to let everyone know that I’d love them to check it out and if you feel it is useful, or if you feel it’s silly, let me know. Constructive criticism welcome! How can I improve it… Or even if I’ve done something horribly wrong.


What are the advantages over gen_statem except simplified model?


Thanks for the question. I’ll be honest, I wrote it because I needed a state machine in a week and couldn’t wrap my head around gen_statem. Then I kept adding things onto it once I had incurred sufficient technical debt on my own project :sweat_smile:

That’s an Erlang lib, right? Well, I appreciate having an Elixir lib. I find Elixir more approachable than Erlang. I know there is interoperability, but approachability is much more than that. I’m comfortable digging into the code and using most Elixir libs. I can’t say the same about Erlang.

It is OTP lib, which mean this is builtin into your distribution already. Also it is used in almost the same way you use GenServer with exception that you do not have “wrapper” module for it. And in this case Elixir wouldn’t help much as it uses dynamic function resolution (when used with :state_functions callback mode), so documentation would be almost the same. Only “handy” thing that such “wrapper” could do is to provide child_spec/1 function for you, but otherwise there would be almost no difference.


For future reference:


Thanks for the elixir translations! Whew, that’s much easier to understand than the erlang docs.
I now see that gen_statem is quite different from how my library works. In gen_statem you send event and in your event catcher you must implement turning over the state yourself. In Statex, the engine will turn over the state (unless interrupted via a fail condition), and you get a notification that this has happened if you register a listener.

From a theoretical perspective these are equivalent, but from code organization principles (and way of thinking perspective) these are different… and I see why I didn’t understand gen_statem. I can’t say which is better from a performance and reliability perspective, but gen_statem is probably more battle tested.

There is also an 3rdParty Elixir wrapper for gen_statem.