Hacker News new | past | comments | ask | show | jobs | submit login

One thing formal state machines make difficult is component reuse.

Let's say you have a music playback control component you wish to reuse across a feature rich player, as well as a mini playback controller.

You COULD just use the full state machine to power the mini player, but most of the transitions would be unused. It would be unclear to the next maintainer which aspects were needed for each use case, thus making the state machine brittle.

Instead, you can write an independent playback progress/state class, and reuse it in both players via composition and proper layering of functionality.

By hiding the playback state from the rest of the player and exposing control of it's state via an interface, you've gained functional reuse.

Reapply the same pattern for all components of your players and you'll find that your product is safer to change and easier to understand than if you had built a complicated formal state machine covering all possible music player use cases.




Ah... your "independent playback progress/state class" is another state machine, just better with an architecture that suits your use case. "Full state machine" is a misnomer and common misunderstanding of the power of state machines. Any state machine bordering on complexity that is hard to manage can be broken into multiple smaller, easier to grasp and manage state machines. And state machines transparently integrate with functional programming, so any ideas contrary to that is yet another misunderstanding of them.


I wouldn't consider this class a state machine in the sense described in the paper.

Any class managing state exclusively is an implicit state machine, no?


This was a nice thing in the example from Raganwald's blog post. The `transitionsTo` decorator:

  function transitionsTo (stateName, fn) {
    return function (...args) {
      const returnValue = fn.apply(this, args);
      this[STATE] = this[STATES][stateName];
      return returnValue;
    };
  }
By separating the state transitions from the state actions in this way it allows the functional components to be reused much more easily. You can construct the miniplayer using only the states you need with only the transitions you need (rather than obscured/hidden capabilities).


This is a nice approach, thank you for pointing it out.

I'd argue that you are building a separate state machine for the two players, but there is some reuse possible in this approach.


Reuse is important, but realistically, how much code is actually re-used? Sure, you have a lot of meaningful subcomponents or libraries that should be correctly isolated for re-use (and really, for testing purposes) but moving a state machine into the core of an application and away from segmented components and libraries hardly harms whatever reuse is likely to happen.


As a developer for backoffice apps (not shown in front of the clients, only our co-workers use our tools), since our team found a state-machine behavior for our framework (means easy to re-use on different project, just change the diagramm/steps conf), we cover more than 95% of the needs that was asked as 'workflow' needs.




Consider applying for YC's Fall 2025 batch! Applications are open till Aug 4

Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: