# Goals of `actions` The features of the library that `actions` should become. ## Eliminating side-effects ### Why - Reduces the risk of bugs - Code becomes **modular**! - An element/struct can be taken out without any issues, no worries about what it affects: **it only affects things it owns** - Without side-effects it is much easier to **reason about the code** and what it does ### How 1. Making sure every datastructure can **only access it's children** - **Updates flow down** - Optional **requests for more data flow back up** in the return statements 2. Force the programmer to **return the inverse of each action** when an action is 'performed' - This is to make sure every action is well-defined - **Inverse can be tested!** Generate a random state, execute the action, then the inverse. Assert that the new state equals the initially generated state. ## Enabling the API-consumer to easily integrate *undo* and *redo* functionality ### Why Undo and redo functionality is an essential requirement for a lot of software. Users heavily rely on it. ### How 1. Letting the API-consumer implement a function **that receives actions and does something expected based on the action** - This function must **return an action that sets the state exactly back** to how it was before the action was received 2. Letting the API-consumer **specify which actions should merge directly** if executed sequentially. (Example: Microsoft Word removes a whole word when undo'ing instead of removing single characters) ## Allowing the API-consumer to compress a list of actions **Compressing**: reducing the size of the list (as much as possible) without losing changes.
**This can be tested by** generating a random state, execute the action, then the inverse. The state should then match the originally generated state. ### Why > compressing seems more like something you would want to do if you want to keep a difference-log of an application. For example, if you are writing an editor for a game-engine. Whenever the user saves, the current chain could be **compressed an stored to the drive** (where size matters). It could then be used to show the differences between saves to the user (the **minimal single actions required to get to the new state**: "You moved this object", etc.). ### How 1. Enabling the **API-consumer to implement logic for merging** actions 2. Exposing a **function in the API that compresses** a `Chain` of actions (a vector containing actions) into a `Chain` of fewer actions.