Допустимые side-effects в функциях

Меня часто волновал вопрос сайдэфекта в функциях :

  • Допустимы ли они?
  • Когда?

На первый вопрос я знал ответ: Допустимо.
А второй требовал объяснений.

В математике функции имутабельны т.е. они лишь возвращают зависимое от параметров подмножество. В математике нет side-effects в принципе.

В программировании функции делятся логически на два типа

  • Процедуры (Есть side-effects ибо в этом смысл программ, нам нужен некий фукнционал)
  • Функции ( Нет side-effect, и это есть математическая проекция)

Есть подход в написании функций — CQS, а так же CQRS и он имеет альернативное развитие в виде Event Sourcing, в данном контексте речь идет о CQS.

В абстрактных объектах (АТД) side-effects естественно отсутсвтуют.
В реализации же они могут быть и есть большая вероятность что ошибочно… НО!

Есть исключения и я запечатлю их тут:

1) Атомарная логическая операция — когда запрос не имеет смысла без команды, т.е. мы получаем данные и их модифицируем потому что это надо делать всегда. Очевидный пример — извлечения элемента из контейнера. По сути это две функции — “скопировать” элемент для возврата, “удалить” элемент в контейнере, но объедененные в один запрос “достать элемент”.

2) Запрос меняет внутреннее состояние конкретного объекта, но при этом не изменяет инвариант т.е. это логирование, некоторый сигнал (событие), кэширование и т.д.

3) Запрос меняет инвариант объекта чтобы предоставить данные требуемого формата или вида, и перед тем как вернуть данные ввостанавливает инвариант. Например стопка книг и тебе надо нижнюю полистать, ты верхние книги разложишь всторонку (изменение целостности) добравшись до книги, читаешь ее, а потом все ставишь на место.

PS: Ты видел наверное еще такие функции команда/запрос которые возвращают булевое значение или какой нибудь класс. Это функции команды, которые возвращают результат своей работы и это нормально.