A DSL for XState[0] by the co-creator of astro.build[1], cool! But the repo[2] has been archived and there is an active FSM library from the same developer called <i>robot</i>[3].<p>[0]: <a href="https://xstate.js.org/" rel="nofollow">https://xstate.js.org/</a><p>[1]: <a href="https://astro.build/" rel="nofollow">https://astro.build/</a><p>[2]: <a href="https://github.com/lucydsl/liblucy">https://github.com/lucydsl/liblucy</a><p>[3]: <a href="https://github.com/matthewp/robot">https://github.com/matthewp/robot</a>
What I don't like about these state machine DSLs is that they are not really composable at the "machine level". It is a known fact that FSM are equivalent to regular expressions [1]<p><pre><code> Alternatively, a regular language can be defined as a language recognised by a finite automaton. The equivalence of regular expressions and finite automata is known as Kleene's theorem
</code></pre>
I think a cool state machine language would use this fact as a starting point for it's syntax. Another very useful feature would be "functions" to isolate specific repetitive parts of FSM<p>[1]: <a href="https://en.wikipedia.org/wiki/Regular_language" rel="nofollow">https://en.wikipedia.org/wiki/Regular_language</a>
I quite like the concise state machine definitions used in Rodney Brooks' "A Robust Layered Control System for a Mobile Robot"[0]. The first element is the state name, and whatever is returned is the next state.<p><pre><code> (defmodule avoid
:inputs (force heading)
:outputs (command)
:instance-vars (resultforce)
:states ((nil (event-dispatch (and force heading) plan))
(plan (setf resultforce (select-direction force heading))
go)
(go (conditional-dispatch (significant-force-p resultforce 1.0)
start
nil))
(start (output command (follow-force resultforce))
nil)))
</code></pre>
[0] <a href="https://www.semanticscholar.org/paper/A-robust-layered-control-system-for-a-mobile-robot-Brooks/fb39b30187babe9bee4afb30b034b5f93b74859a" rel="nofollow">https://www.semanticscholar.org/paper/A-robust-layered-contr...</a>
At one point I built a type-based state machine core for Java. The idea was to use interfaces and classes as the basis for defining what transitions are allowed, and as a way to store the associated fields. It relied on Java's type-checking to guide you into using it correctly.<p><pre><code> public interface TurnstileState {}
public interface LockedState extends TurnstileState {}
public class UnlockedState implements TurnstileState {
public final int credits;
public UnlockedState(int credits) {
this.credits = credits;
}
}
public static final LockedState LOCKED = new LockedState() {};
StateMachine<TurnstileState> turnstile = StateMachine.<TurnstileState>.newBuilder()
.addValidTransition(LockedState.class, UnlockedState.class)
.addValidTransition(UnlockedState.class, LockedState.class)
.addValidTransition(UnlockedState.class, UnlockedState.class)
.buildWithInitialState(LOCKED);
turnstile.transition(new UnlockedState(1));
</code></pre>
I never got around to building out examples in Kotlin. I feel like the type checking there would streamline a ton of this even further.<p><a href="https://github.com/Hounshell/st8">https://github.com/Hounshell/st8</a> if anyone wants to see the gory bits.
One thing that saddens me is how Ragel petered out, I guess they got bit too ambitious with the Colm rewrite. But it was a state machine language that saw a blip of usage at one point
There is also vintageish SCXML underwritten by the w3c, with the panoply of xml friends (an xsd schema hence validator, xpath queries and xslt transforms). Also being part of the uml chart family it should be xmi-borne, if you wondered.
> This repository has been archived by the owner on Dec 12, 2023. It is now read-only.<p>Hasn't been updated in 4 years, and is now archived, so I assume this project is dead. Looks good though!