Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[feat] an equivalent for gen_statem #50

Open
bunopnu opened this issue Oct 2, 2023 · 10 comments
Open

[feat] an equivalent for gen_statem #50

bunopnu opened this issue Oct 2, 2023 · 10 comments

Comments

@bunopnu
Copy link

bunopnu commented Oct 2, 2023

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.

@lpil
Copy link
Member

lpil commented Oct 2, 2023

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.

@bunopnu
Copy link
Author

bunopnu commented Oct 3, 2023

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.

@lpil
Copy link
Member

lpil commented Oct 3, 2023

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?

@bunopnu
Copy link
Author

bunopnu commented Oct 3, 2023

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...

@lpil
Copy link
Member

lpil commented Oct 3, 2023

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.

@bunopnu
Copy link
Author

bunopnu commented Oct 3, 2023

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.

@lpil
Copy link
Member

lpil commented Oct 3, 2023

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.

@bunopnu
Copy link
Author

bunopnu commented Oct 3, 2023

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. 😅

@lpil
Copy link
Member

lpil commented Oct 3, 2023

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.

@dvic
Copy link

dvic commented Jul 24, 2024

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

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants