Функция без побочных эффектов (она же "чистая") - это функция, которая для одних и тех же аргументов всегда возвращает один и тот же результат и сама не вызывает функций с побочными эффектами.
Непонятно, зачем только эта рекурсивная добавка в определении.
Такая функция будет вносить (вообще говоря) побочные эффекты в выражения в которых она вызывается.
И вы сделали акцент на
влиянии внешнего окружения на функцию (на ее результат), таком влиянии, чтобы ее результат зависел только от значения ее фактических параметров, то есть не зависел:
- от неявно импортиремых (всеми вызываемыми в ней процедурами) внешних переменных (но допустима зависимость от констант и других процедур),
- от разыменованных переменных взятых от ссылочных компонент ее параметров,
- от ссылочных значений созданных при ее вызове.
В то время как побочный эффект есть
влияние функции на внешнее окружение.
Все остальные предложенные "разновидности" - не знаю для чего могут понадобиться.
Для того чтобы сделать все выражения без побочных эффектов, они и понадобятся.
Если все функции всегда не изменяют внешнее окружение, а операторы не выдают значений и тем самым не входят в выражения (хороший, годный язык), то все выражения не имеют побочных эффектов.
Я за то, чтобы все функции (а значит и выражения) обязательно были без побочных эффектов, и это проверялось компилятором консервативными методами (по структуре ее ввода-вывода). Конечно, некоторые функции без побочных эффектов будут при этом отсеиваться, те, чья проверка их безпобочности будет неконсервативна, а то может быть и вовсе неразрешима.
А вот условие чистоты функций для меня не обязательно, хотя его проверку тоже можно втиснуть в консервативные рамки и сделать обязательной при компиляции.
Применительно к данной задаче чистая функция могла бы возвращать структуру/кортеж. с найденным состоянием.
Только следует быть осторожным при возвращении ссылки на структуру или структуры со сслылочными компонентами. При одних и тех же аргументах, функция может выдавать структурно одинаковые результаты, но с разными значениями ссылок, т.е. формально другой результат.
Тогда для чистоты придеться явно вносить в вызов функции ссылочные компоненты ее результата - через фактические параметры.
Следует также помнить, что разыменованные ссылочные компоненты результата функции в сам результат уже не входят и не существенны для вопроса одинаковости и различности результатов функции. В частности, если результат функции есть ссылка, то ее результат ограничивается лишь этим ссылочным значением. Это же относится и к ее аргументам.
Кроме того, что функция может быть чистой и грязной (с побочными эффектами), она ещё может быть тотальной (гарантированно успешно завершится) и не тотальной (может выдать ошибку или никогда не завершиться).
Например, f(x)=5/x может выдать деление на ноль, и хоть она и является чистой, тотальной она не является.
Выход из функции по ошибке не является побочным эффектом, т.к. находится вне среды исполнения программы, т.е. вне видимости языка.
Если параметр-переменная "заяц" здесь ссылочная, то присвоение "результата" функции переменной заяц^, это само по себе глобальный эффект.
1. Я не считаю конкретно это изменение ПОБОЧНЫМ эффектом - хотя конечно это изменяет глобальное окружение
2. Вы черезчур сильно обобщаете свои рассуждения - следуя этому пути можно всегда предположить, что в одной из этих процедур есть и традиционный побочный эффект (прямое изменение значения глобальной переменной не передающейся через интерфейс подпрограммы).. а раз так то и задача не имеет смысла...
1. А я считаю, по этой же причине. Такая "функция" является тривиально чистой, она тождественная, потому что "результат" здесь это само ссылочное значение "заяц" (а не "заяц^") равное ссылочному аргументу "заяц" (если конечно "функция" не меняет его значение).
2. Изменение значения глобальной переменной даже передающейся через интерфейс подпрограммы (как параметр-переменная) тоже является побочным эффектом. У функции без побочного эффекта не должно быть VAR/OUT-параметров.
Почему задача не имеет смысла? Не обязательно использовать функции. Требования использовать функции без побочного эффекта тоже нет в условии задачи. Только минимизация числа извлечений и сохранение промежуточных результатов.
Любое изменение глобального окружения функции внутри неё является побочным эффектом, будь-то ввод/вывод, прямое или косвенное изменение глобальной переменной.
Если функция хоть как-то влияет на изменение глобального (по отношению к ней) состояния программы, то эта функция имеет побочный эффект.
Если так рассуждать - то Хаскели и проч. "чистые" ФЯВУ - не только таковыми не являются - но потенциально гораздо более опасны чем императивные ЯП.
"Чистые" ФЯВУ по сути это одни выражения, и никаких операторов.
Если мы хотим изменить "глобальное окружение" в "чистом" ФЯВУ (например, записать в лог), мы должны влючить значение этого "глобального окружения" в параметр функции, а затем вывести новое значение этого "глобального окружения" как компоненту результата.