otp icon indicating copy to clipboard operation
otp copied to clipboard

[feat] an equivalent for `gen_statem`

Open bunopnu opened this issue 2 years ago • 10 comments
trafficstars

Hi,

The gen_statem behaviour provides a powerful way to manage stateful processes, especially for development of complex state machines and stateful systems.

It would be great to see something similar for Gleam.

bunopnu avatar Oct 02 '23 19:10 bunopnu

Could you go into more detail as the specific requirements for this new process abstraction, including the sorts of problems you would solve using it, and what a typed API might look like? Thank you.

lpil avatar Oct 02 '23 20:10 lpil

Requirements

I don't think it should be actually same with gen_statem, but should be a module that simplifies the process of creating FSMs in Gleam, making FSM implementation more accessible and straightforward for most of the case.

Use Cases

Many services, like chat servers and database connections involve maintaining state across multiple interactions. The new equivalent can provide a clean way to manage such states. It can be also used to manage resources like database connections and network sockets for ensuring proper initialization, use, and cleanup.

Implementation

I'm currently considering an approach based on the actor module to seamlessly integrate the new abstraction within the existing hierarchy. To explore this idea further, I plan to develop a prototype library that demonstrates how something similar to gen_statem can be implemented in Gleam.

bunopnu avatar Oct 03 '23 04:10 bunopnu

Given Gleam is a typed language how could a library create a finite state machine? They are typically created using types, which the programmer defines.

Assuming there's a good design for a library creating FSMs, why would it be part of gleam_otp rather than a stand alone package that isn't coupled to a particular concurrency abstraction?

lpil avatar Oct 03 '23 11:10 lpil

Given Gleam is a typed language how could a library create a finite state machine? They are typically created using types, which the programmer defines.

I don't think that being a typed language is an issue here, as there are already libraries available for typed languages. Checking their implementations may assist us in developing one for Gleam.

Assuming there's a good design for a library creating FSMs, why would it be part of gleam_otp rather than a stand alone package that isn't coupled to a particular concurrency abstraction?

You are correct; I had considered this repository because it's within Erlang/OTP. Maybe leaving this to the community might be a better choice...

bunopnu avatar Oct 03 '23 13:10 bunopnu

Could you share some of those libraries? I was unable to find any for well typed languages without macros, and the ways I know of making FSMs don't have anything that be extracted in to a library.

lpil avatar Oct 03 '23 15:10 lpil

I've come across several state machine libraries:

  1. Stateless
  2. Stateless (for Go)
  3. ZigFSM

I'm not entirely certain if these libraries employ any behind-the-scenes magic. Particularly, the ZigFSM appears quite clean and straightforward.

Maybe we can also consider the Elm architecture, as it resembles me a state machine.

bunopnu avatar Oct 03 '23 15:10 bunopnu

Sorry, to be clear I mean languages with very robust type systems like Gleam, so OCaml, Elm, Rust, etc.

Go, Zig, and C# are statically typed, but their type systems are much less strict then Gleam's, so they're not very useful references as what works in them tends not to work with a stronger type system.

edit: Looking more at those libraries I think they're largely replicating Gleam's case expressions, so in a Gleam program we could have a similar experience without any library boilerplate, just using the language itself.

lpil avatar Oct 03 '23 15:10 lpil

It's my fault since I'm not entirely sure how the type system works in Gleam. I used to believe that functions in Gleam could optionally have their argument and return types annotated, which would somehow enable library users to use their own Event and Message types.

However, I'm currently feeling confused about this. 😅

bunopnu avatar Oct 03 '23 15:10 bunopnu

I think a good way to approach this would be to implement some of these protocols and see what sort of code arises when doing it in Gleam. Once we've done a few iterations of this we can figure out if there's any abstractions that can be lifted out of those production tested solutions. Trying to make a solution without specific problems often results in a weaker solution in my opinion.

lpil avatar Oct 03 '23 15:10 lpil

Just sharing a nice example of using gen_statem in Elixir: https://andrealeopardi.com/posts/connection-managers-with-gen-statem

dvic avatar Jul 24 '24 07:07 dvic