"Design, maths & framework".
The "you really should read" Pure UI and Pure UI Control articles defined an approach to app development (design and creation) which resolves to these 3 words. If their approach to maths is extended slightly to include testing, then we can say these 3 words constitute a comprehensive but simple waterfall development process.
I find this an attractive simplification, in which maths helps developer's lives become easier, less stressful and less process-dependent.
Design defines the appearance and the core states and transitions. Maths formalises the states and transitions, whilst visually and collaboratively supporting the investigation of missing details and then auto-generating tests. The app framework simply instantiates those states and transitions.
The essence of 'Pure UI', as eloquently described in the articles at the beginning of this post, is a smooth interaction between design and business logic. UI is really a side-effect of the business logic, or state management. The chosen solution to provide this apparent magic is state charts. It doesn't really matter which framework you use, so long as it's functional and state -> UI is uni-directional!
State charts are a well-described mathematical concept (an intro and some resources) which extend the simpler state machine. The core principles are the definition of states, transitions between states and actions to take in consequence. Optional extras are the management of state and implementation of the actions (I prefer to let the app or UI framework deal with these).
A state chart allows reasoning about function without concern for implementation details - it is therefore easier. In particular, visualisation of a state chart enables easy collaboration with designers and rapid prototyping (or updating) of function. The linked visualisation is from the app example in 'Implementation options' below, and is a simple copy-paste of a state chart from the machines.js file in that app. A state chart designed in this way can therefore be used directly in code.
Much, of course, is written about unit tests. Functional programming, a natural fit for state machines and React or Hyperapp means unit tests are reasonably straightforward. What is always less so is testing business logic, or the interactions between functions and state which happen when the UI generates related sequences of events.
Cypress can automate business logic testing if state chart 'paths' are provided, which represent automatically generated routes or sequences of transitions. XState has a graph module which does this.
There are less than 10 simple app-specific lines of code, amongst re-usable functions, which drive the Cypress test of each app state and valid 'path'. You can watch the test video 'live' here and the app is hosted here (it is a simple media creation PWA, which doesn't send data anywhere but asks for video, audio and push notification permissions).
New requirements simply filter in from the top, via design updates and logical consequences of state chart changes. In principle the tests will automatically update as a function of the state charts (in practice some small amount of manual input may be required).
There are some details to work out regarding the specific boundary of responsibility between the maths and the app framework (e.g. exactly who hosts the state) but these don't change the principles.
For instance, in this example, the Hyperapp framework is responsible for managing state and executing actions. However in this example React is largely just an interface to the browser's DOM whilst the state chart (from XState) manages state and action execution. Specifically in this case, DOM events are linked to a React Hook which triggers a state transition - the state chart does the rest.
A very useful (but little written about?) state chart feature is that they can automatically provide app use-cases as sequences of state transitions. These sequences, or paths, can be used as the basis for testing - this example drives Cypress in this way. The repository is here - use the 'xstate' branch.
So there you have it - a waterfall dev process that is much simpler and friendlier than I remember. And some maths that isn't scary and is useful!
An example development process flow might look something like this:
State chart maths in XState.
Testing can be derived directly from the state chart maths and implemented with Cypress.
Requirement changes can quickly be incorporated into design and state chart maths updates, which (generally) require simple UI framework tweaks.
Most people want to make things perfect. Sometimes we evaluate the complexity of an upcoming goal or a problem. So, the fear to not complete it perfectly or "wrong" (Yeah, who are judges? 🤔) stops us even from trying.