Взаимоотношения чистых и детерминированных функций
Для начала, вспомним каждое из определений. Чистая функция – это функция, которая не имеет побочных эффектов и для фиксированного набора аргументов возвращает один и тот же результат. Давайте посмотрим на пару примеров.
Чистые функции
Вот функция _sum:
def _sum(a, b): return a + b
Результат её работы не зависит ни от чего, кроме аргументов, и не делает ничего с окружающей средой.
А вот _weighed_sum:
def _weighed_sum(a, b): return a * WEIGHT + b
Эта функция «грязная»: результат её работы кроме «a и b» зависит ещё от глобальной переменной WEIGHT. Получается, если мы зафиксируем значения аргументов функции, мы не сможем гарантировать, что результат всегда будет один и тот же.
Теперь посмотрим на _save_sum_to_database:
def _save_sum_to_database(a, b, cursor): result = a + b cursor.execute(“INSERT INTO sum_results (result) VALUES (%s)”, result)
Эта функция тоже «грязная»: она использует базу данных и результат её работы зависит от БД. Функция будет вести себя по-разному, если БД доступна и недоступна.
С чистыми функциями разобрались! Они используют только свои аргументы, не ходят во «внешний мир» и гарантируют один и тот же результат при тех же аргументах.
Теперь вспомним, что такое детерминированные функции
С ними всё проще: детерминированные функции возвращают один и тот же результат для одних и тех же аргументов. В общем случае детерминированный алгоритм – это алгоритм, поведение которого можно полностью предсказать по входным данным.
Простой пример недетерминированной функции – randint. Входные аргументы мы знаем, а результат – нет.
Если внимательно посмотреть на определения чистых и детерминированных функций, то станет понятно, что чистые функции – подмножество детерминированных.
Это важный вывод: зная это, становится проще понимать свойства разных кусков кода и делать их чище.
Есть вопрос? Напишите в комментариях!