Anybody using a modern SPA framework (React/Angular) is dealing with Hierarchical State Machines, whether they are aware of it or not.
Take for example React with a router. When you are in a given view, that component is your active state. Nested views are nested states of that component. Entry and exit actions are executed within the lifecycle hooks (componentWillMount, componentWillUnmount).
We take these concepts for granted because we're used to working with them, but if you tried to make a multi-view/nested-view single page application using only, for example, jQuery...you would find that there was a reasonable amount of complexity arising from state teardown and mounting. And if you found the exercise to be trivial, then I would be willing to bet that your resulting structure could be classified as something akin to a Hierarchical State Machine :)
I couldn't disagree more. The inability to send events to stateful components in any convenient manner (and you'll cop an earful for not being "reacty") means you have to extract all your state machines out of your react components.
Samek created quantum leaps [1], an open source implementation of HSMs designed for use in embedded or realtime applications.
If you've ever designed something that should respond to requests/activity, you probably understand the challenge of representing and understanding the multiple concurrent states your software system inhabits. HSMs (aka statecharts or Harel statecharts) are a great way to model this problem domain.
The tricky thing with abstract class (oop) hierarchies is that deeply nested ones tend to be
1. hard to understand because parent behavior is shared concretely rather than modeling it behind protocols.
2. hard to change without breaking lots of dependent code because the dependencies are not obvious.
3. hard to debug because state internals easily leak out of parents and into children.
I wonder how they're managing this problem in HSM's. Seems like transitions between parent/child states would need some kind of protocol to define state entry/termination criteria so that the concrete dispatch mechanisms themselves could be abstracted away from the parents/children.
I recently started a job where I was introduced to HSM's. The answer is, there isn't one. The resulting C reads like the entire program was written in main() and connected via glorified gotos. Every module depends on a global event queue, and event data is passed via circular dependency on effectively global state. I have never seen such basic logic so obfuscated and so distributed.
It might just be this codebase, but I do not see the appeal to HSM's. I'll stick with my standard flow control (while, for, break, return) and compose functions from other functions. It sure is nice to make calls that actually return.
Hmmm. I created a system I called Sub-Machines back in the 80's too, though it never occurred to me that anyone else might be interested in it. I was particularly focussed on data communications protocol state machines. I could launch and detach, launch and camp (block), and launch and continue with other business until notified of a submachine's completion. Such notifications could also wake up camped super-machines. I could also get progress notifications bubbling back up. Worked a treat. To make it work I also had to create a co-operative function based multi tasking scheduler. It was very fast, and I still use it to this day. Part of the speed is not having to save context on every task switch. Takes planning though, unlike the lazy while(true) thread loops invented for junior programmers and used today way too much. But no real hardship when dealing with event driven systems, where each event has usually pretty short computations. Much easier to get true Hard Real Time systems to meet their targets.
Statecharts are used a lot in model-based design in automotive software development. I especially like a tool called IBM Statemate it was lightweight and easy to extend compared to Simulink.
One key issue in the tooling however (which is perhaps applicable to all "visual" programming languages) is the inability to view proper 'diffs' of changes. This was eased in Statemate somewhat because all statecharts were stored as plain text files but I feel it could use some good ideas.
I have used ASCET, another model-based design tool. It exports the models as XML and has a separate executable that diffs the XML and renders the diagram with red outlines around the changes so you can click down into the details of the changes.
12 comments
[ 2.4 ms ] story [ 32.4 ms ] threadTake for example React with a router. When you are in a given view, that component is your active state. Nested views are nested states of that component. Entry and exit actions are executed within the lifecycle hooks (componentWillMount, componentWillUnmount).
We take these concepts for granted because we're used to working with them, but if you tried to make a multi-view/nested-view single page application using only, for example, jQuery...you would find that there was a reasonable amount of complexity arising from state teardown and mounting. And if you found the exercise to be trivial, then I would be willing to bet that your resulting structure could be classified as something akin to a Hierarchical State Machine :)
If you've ever designed something that should respond to requests/activity, you probably understand the challenge of representing and understanding the multiple concurrent states your software system inhabits. HSMs (aka statecharts or Harel statecharts) are a great way to model this problem domain.
[1] http://www.state-machine.com/
which led me to David Khourshid's worthwhile "Infinitely Better UIs with Finite Automata" presentation, https://www.youtube.com/watch?v=VU1NKX6Qkxc
and the article "You are managing state? Think twice", http://krasimirtsonev.com/blog/article/managing-state-in-jav...
https://aleph2c.github.io/py-activeobject/index.html
It's not done yet, but seeing this post on the front page of hacker news was too tempting for me not to share.
I wonder how they're managing this problem in HSM's. Seems like transitions between parent/child states would need some kind of protocol to define state entry/termination criteria so that the concrete dispatch mechanisms themselves could be abstracted away from the parents/children.
Maybe its just me.
It might just be this codebase, but I do not see the appeal to HSM's. I'll stick with my standard flow control (while, for, break, return) and compose functions from other functions. It sure is nice to make calls that actually return.
One key issue in the tooling however (which is perhaps applicable to all "visual" programming languages) is the inability to view proper 'diffs' of changes. This was eased in Statemate somewhat because all statecharts were stored as plain text files but I feel it could use some good ideas.