edisonywh/gearbox

Enhancement Proposal

blisscs opened this issue · 7 comments

Hi,

First of all, thank you for publishing this library.
I was looking for gen_server_less implementation of machinery that does not come with web dashboard part also.

I have read through the code and tests. It's exactly what I wanted.

I have some recommendation/feature requests -

  • Instead of using String data type for the state. I think we could let the state be of any types. for example, a tuple to represent a coordinate on x-y plane {0.0, 0.5}, or a list, or any other types.
  • Instead of using the :field to set the key to fetch the state from a map or a struct. I think we could use an anonymous function instead of string or atom key as a function to fetch the state out from data of any types.

My idea is that anything can have its own state, it could be a String, a Number, a Struct, a List.
Then we send this into mentioned above anonymous function to get the actual state out.

Let's me know what do you think of it.

👋Hey! I'm glad that I wasn't the only one wishing for the same thing, haha!

Thanks for creating this issue! I think allowing any arbitrary term is a really cool idea, I really like that! That could certainly open up to a lot of possibilities.

However, I guess one main concern that I have is more of just the practical use cases of it. Having that possibility is great, but I struggled to come up with a practical use case for it. I don't want to implement something for the sake of implementing but would rather do it to solve a problem instead.

Perhaps we could come up with some realistic examples before deciding on this, so that the problem statement is clearer. Do you have a better idea/example of applying this in a real-world scenario?

Thanks again for the issue! :)

Hi @edisonywh,

I also don't have realistic use cases for now.

One sample I could think of is -
Imagine we are modeling a chess game.
the possible states for any chess pieces could be {0,0},{1,0}...,{8,8}.
where {n,n} represents a square on a chessboard.

The current state for chess piece could be one of {0,0},{1,0}...,{8,8}.

And the valid transition to states for it could be {0,0},{1,0}...,{8,8}

If in this case -

  • I would prefer to model a chess piece state a tuple of {i,i}.
  • and for storing state in DB, I would create a struct of %ChessPiece{type: "King|Queen|Other", x_position: [0..8], y_position: [0..8], alive?: true} or in any other forms

I think to be precise the state of the chess piece could be {"King", 0, 0, true} or {"Queen", 0, 5, false}

If you see from my above sample, I think by allowing a complicated state to be berived from any data structure instead of explicit put a state in the key of a map or struct. We can easily model more sophisticated state machines and we do not think much about making everything in map or struct.

Hi guys! Not really agreeing or disagreeing with @blisscs 's idea for having more than just a String as a state, but I wanted to point out that the chess example above might be a bit oversimplified. If you're talking about defining ALL possible states of a chess piece, that sounds like it might be a very very big number of states. I'm no real expert in these things, but determining where a piece can move sounds like it should be more of a rule based kind of system, rather than a state machine kind of thing. I might be wrong, but that's what I kind of feel (I'm no mathmagician)

Hi @Fadhil,

I agree with you that it would be better off designing chess piece transitions above this using rule-based kind of system.
The main point that I would want to focus on is a state could be derived from any data structures not just from the field in the map or struct.

@blisscs

I hear ya. Maybe a better example might be if you want to ensure the readiness of an airplane to take off. You might have a tuple like {<moving/stopped>,<disembarking/boarding>, <refueling: true/false>}. I'm sure there must be other (real) use cases that could involve multiple factors in determining the state of a thing.

That being said, maybe defaulting to strings but allowing the user to override the types when they want to might be a good idea. Some kind of Behaviour implementation?

@Fadhil
Thank you for puting a good example up.
This is what I want to say, but only a different is that what i am proposting is not to default to string value and not to fetch the state out from the map or struct also.

And we could do that by also give another annoymous function to a state machine, during the time we define a statemachine. This annonymous function will be used to get the actual state out from any data structure.

@blisscs @Fadhil Thanks for the great discussion guys!

I do really like the idea with using any term as key, feels pretty idiomatic Elixir/Erlang-like to me.

However I still think this could end up complicating Gearbox (both in terms of usage and the internal implementation itself), and since there's not a compelling enough use-case/reason to do that, I'll rather not to make that tradeoff right now.

I think what we should do is to open this up to discussion/request for comments and see if anyone else have any other points of discussion or even a better real-life use case for this, feel free to get people to chime in here.

Thanks anyway for your idea! Really appreciate that :)