DEV Community

Cover image for You don't need a library for state machines

You don't need a library for state machines

David K. 🎹 on January 20, 2021

The finite state machine is one of the oldest models of computation in computer science. It's older than the web, older than any programming langua...
Collapse
 
darkwiiplayer profile image
𒎏Wii 🏳️‍⚧️

I've always liked the idea of using coroutines and tail-calls to represent state machines. Each state is a function and transitions into another by simply tail-calling it. Input/Output is done by yielding the coroutine.

Sadly, not many languages have the tools needed for this: Tail call elimination and stackful coroutines.

Collapse
 
davidkpiano profile image
David K. 🎹

Yeah, I didn't mention coroutines/generators because the article would be twice as long!

Collapse
 
nbilyk profile image
Nicholas Bilyk

<3 Kotlin

Collapse
 
darkwiiplayer profile image
𒎏Wii 🏳️‍⚧️

I've had a quick look at kotlin "coroutines" and they seem more like light threads to me than actual coroutines.

Thread Thread
 
nbilyk profile image
Nicholas Bilyk

Coroutines in Kotlin use threading strategies, so for example you can have a common pool for greenthreading, you can have a main thread for UI, a dedicated thread for IO, or no threading for environments like web that don't support it. Threads are a part of it, but kotlin coroutines at their core is really just a way to do parallel work without callbacks.

Thread Thread
 
darkwiiplayer profile image
𒎏Wii 🏳️‍⚧️

That's... not what coroutines are though...

Thread Thread
 
nbilyk profile image
Nicholas Bilyk

Ok, get into that debate with them then.

Thread Thread
 
darkwiiplayer profile image
𒎏Wii 🏳️‍⚧️

It's not really a debate. If they want to call their green threads coroutines, that's their choice. I just find it confusing, because I'm used to coroutines being actual coroutines.

Collapse
 
sukima profile image
Devin Weaver • Edited

I started my FSM/Statechart journey rolling my own as well. I now have a go-to micro-fsm I use for personal projects. Because I followed the same object structure as above I can quickly move to XState as the logic becomes more complex. tritarget.org/Micro%20State%20Machine if anyone is interested.

Collapse
 
joaozitopolo profile image
Joao Polo

I just added the xstate lib on my react project to control things...
I done three comparisons:

  • with "useState", the more confuse approach because I can have intermediary steps (for example, I can set loading by true, but I already have old data on other fields)
  • with "useReducer", a clear method, but so verbosely
  • with "useMachine" (xstate lib), a clear and not so big implementation like useReducer.

But for me, it's not the best approach, yet... maybe the old immutable objects approach should be a better solution. I'll try it also.

Thanks for your article, it was awesome to read.

Collapse
 
xavierbrinonecs profile image
Xavier Brinon

and what is missing here is the possibility to go back in time and reprocess the whole journey when you want to debug something (looking at you, beautiful redux).

Collapse
 
darthwalsh profile image
Carl Walsh

I too love event sourcing

Collapse
 
simon_boddy profile image
Simon Boddy

My answer to this is directed acyclic graphs. When you organize your state-and-behaviour into a DAG, you get an application that's intuitive (methods live with the state they modify), rigorous (a graph traversal ensures something like one way data flow) and easy to reason about (your graph can be visualized).

Octopus, which I wrote, implements this for js apps. As far as I'm aware it's the first reusable implementation of a DAG for app development.

github.com/bbsimonbb/octopus-turbo

Collapse
 
raphaelmansuy profile image
Raphael MANSUY

Thanks David 👏 Great article. I am a big fan of this approach 🔥

Collapse
 
aurelmegn profile image
Aurel

There is a more Object oriented approach using the State design pattern. It helps to have a cleaner code (en.wikipedia.org/wiki/State_pattern)

Collapse
 
davidkpiano profile image
David K. 🎹

Right; if you want to use OOP, you can. It's basically the same thing as switch-case + functions (substitute methods for functions).

Collapse
 
joaozitopolo profile image
Joao Polo • Edited

XState versus Object approach
xstate vs object approach

Collapse
 
papercoding22 profile image
Paper Coding

This looks like how redux works

Collapse
 
davidkpiano profile image
David K. 🎹

Sort of... Redux doesn't completely embody this pattern though: dev.to/davidkpiano/redux-is-half-o...