0

tl;dr

In a program that calls a function onEnterFrame on each frame, how do you store and mutate state? For instance if you are making a level editor or a painting program where keeping track of state and making small incremental changes are tempting / enticing / inviting. What is the most performany way to handle such a thing with minimal global state mutations?

long version:

In a interactive program that accepts input from the user, like mouse clicks and key strokes, we may need to keep track of the state of the data model. For instance:

  • Are some elements selected?
  • Is the mouse cursor hovering over an element, which one?
  • How long is the mouse button held down? Is this a click or a drag?

We also, sometimes need make small changes to a large model:

  • In a level editor, we may need to add one wall to an existing large set of prefabs. You don't want to recreate the set, no?

Read Prof Frisby's mostly-adequate-guide so far, there are many functional solutions to issues that deal with extracting a piece of data from some source of input, performing computation on that data and passing the result to some output.

Sometimes an app let's the user interact and perform a sequence of mutations on data. For instance, what if a program let's the user draw (like Paint) on a canvas and we need to store the state of the painting as well as the actions that led to that state (for undo and logging/debugging purposes)?

What state is acceptable to store and what should we absolutely avoid? Currently my conclusions is that we should never store state that we only need temporarily, we should pass it to the function that needs it directly.

But what if there are several functions that need a specific computation? Like the case in which we check if the mouse's cursor is hovering over a specific area, why would we want to recompute that?

Are there ways to further minimize mutations of global state?

AturSams
  • 7,568
  • 18
  • 64
  • 98
  • I realize that my question is a poor duplicate of this question: http://stackoverflow.com/questions/1020653/how-can-you-do-anything-useful-without-mutable-state – AturSams Apr 25 '17 at 15:27
  • I recommend reading this: http://prog21.dadgum.com/23.html – AturSams Apr 25 '17 at 17:49

1 Answers1

1

Storing state isn't the problem. It is mutating global state that is the problem. There are solutions to handling this. One that comes to mind is the State Monad. However, I am not sure this is ideal for undoing operations. But it is a place to start.

If you just want to look at the problem as an initial state and a set of operations then you can think of the operations as a List that can be traversed (with the head being the latest operation). Undoing a set of n operations could be accomplished by traversing the first n elements of the list and cons-ing the inverse of these operations to the list.

That way you don't modify global state at all.

melston
  • 2,198
  • 22
  • 39
  • The distinction between storing global state and mutating global state is not clear because if you are storing state, you are probably updating it? Are you suggestion that if there is some model that is important to some main process, I should inject it to the function that handles that process? – AturSams Apr 25 '17 at 09:43
  • The state monad passes state along to each 'transformation' and returns a new state. That way no global state is mutated. The use of the List is to emulate an event store where state is derived by (for example) 'folding' from an initial state over the sequence of operations to some final state. Again, no mutating of global state is required. – melston Apr 25 '17 at 21:49