Friday, 24 May 2019

How to implement settable and retrievable state without mutation nor reassignment?

There are a couple rules that are arguably good to follow when writing code:

  • Code is easier to read and reason about when there's no reassignment; many linters recommend preferring const whenever possible.
  • Code is also easier to read and reason about when objects do not get mutated. If you define an object in one part of the code, it's helpful to know that you may freely reference that object elsewhere, and it will be exactly the same.

In most cases, these rules are just fine, and both of them can be followed without issue. But is it possible to follow them both when implementing a module which has both setter and getter functionality (which is a very common pattern in programming)? For example:

const module = (() => {
  // Reassignment, but no mutation:
  let savedData;
  return {
    getData: () => savedData,
    setData: (newData) => savedData = newData
  };
})();

module.setData('foo');
console.log(module.getData());
const module = (() => {
  // Mutation, but no reassignment:
  const savedData = { theKey: null };
  return {
    getData: () => savedData.theKey,
    setData: (newData) => savedData.theKey = newData
  };
})();

module.setData('foo');
console.log(module.getData());

I can't think of how one could possibly implement something like this without either mutating or reassigning somewhere - but such things should be avoided. Is what I'm looking for possible, or is it simply a fact of life that I must choose one or the other, and I should just shrug and pick one?

If I called the module with the data to set it with initially, and never set its data again, it would be possible, but this approach is very inflexible and will not fulfill most useful use-cases.

const makeDataHolder = (savedData) => {
  return {
    getData: () => savedData,
  };
};

const fooData = makeDataHolder('foo');
console.log(fooData.getData());

I'm not necessarily looking for a solution that follows all the principles of functional programming (though, if one exists, it'd be interesting to see), but this general problem is probably familiar to those who use functional programming.



from How to implement settable and retrievable state without mutation nor reassignment?

No comments:

Post a Comment