Hacker News new | ask | show | jobs
by syngrog66 1099 days ago
A state machine (specifically a FSM) class is something I end up having to reinvent in every new language I've adopted. Such a useful pattern whose need comes up repeatedly. Especially in games/sims or in anything with a GUI. Since I've been making both for decades I have a lot of homegrown FSM classes sitting around. :-p
1 comments

I am working on a state machine formulation/notation that can be executed.

The runtime is multithreaded and parallel.

The idea is to execute the following state machine:

  thread(s) = fact(variable) | send(message) | receive(message2);
  thread(r) = fact(variable) | receive(message) | send(message2);
This program waits until thread(s) is true in another thread until thread(r) is true, everything left of the equals symbol needs to be true before it passes to the next group of facts after the = symbol. Then it waits for "fact(variable)" to be fired, then when all those atoms are true, the state transitions past the pipe symbol and does a send(message) while the other thread does a receive(message) and then the process is repeated in the opposite direction. I've not shown it here, but you can wait for multiple facts to be true too.

Here's a state machine for an (echo) server that is intended to be mapped to epoll or libiouring:

   accept | { submit_recv! | recv | submit_send } { submit_send! | send | submit_recv }
The curly brackets means parallel state machines that run independently, like a fork.
That is a description of flow-based programming, minus the generalization to "arbitrary packets of data in bounded buffers" - that is, your only data type is true/false and your only buffer size is 1, which lets you get some very clean syntax on it. It's a good invention!

FBP adapts the physical concept of unit record machines that operate over punchcard stacks, which predisposes it to thinking in terms of processing and transforming richer data like "characters in a string" or "records in an array", but it basically works for truth-signalling logic too - let truth packets wait in a buffer, and then when the node signals that the packets are able to move, that is the transition.

The emphasis does differ in that if we are thinking "FSM", the rest of the program and the data it handles have been abstracted, while if we are thinking "FBP" we're engaged with designing specific machines to connect together in terms of I/O, which is more helpful when you have a library of data operations to reuse.

Thank you syntheweave for an interesting reply.

You're right about the buffers with a truth value in a buffer. I actually use a style of promises or my own count down latch.

I am inspired by Prolog and Drools, a rule engine. I want to "fire" and "retract" facts and the state machine shall work out what to do next.

Here's something that I find especially useful about the formulation: the state machine only moves in one direction, from left to right, but there are multiple transition signals available (facts/atoms) that can be fired to cause the state machine to move forwards.

If you define multiple independent state machines it should be possible to detect "stuck states" where it is impossible for the state machine to continue progressing! This is useful for liveness analysis.

I want the state machine formulation to be useful in designing distributed systems such as Raft.

love it! shutup and take my money/adoption/usage/attention! ha

no but seriously, sounds like a good/useful plan/approach. please let me know if you share out a spec or impl sometime

BONUS points for a Golang or C lib