«Нормальный» способ сформулировать, что такое чистая функция, заключается в терминах прозрачности ссылок. Функция называется чистой, если она прозрачна по ссылкам.
Ссылочная прозрачность, грубо говоря, означает, что вы можете заменить вызов функции возвращаемым значением или наоборот в любой точке программы без изменения смысла программы.
Так, например, если бы printf
языка C был ссылочно прозрачным, эти две программы должны иметь одно и то же значение:
printf("Hello");
а также
5;
и все следующие программы должны иметь одно и то же значение:
5 + 5;
printf("Hello") + 5;
printf("Hello") + printf("Hello");
Поскольку printf
возвращает количество записанных символов, в данном случае 5.
Это становится еще более очевидным с void
функциями. Если у меня есть функция void foo
, то
foo(bar, baz, quux);
должно быть таким же, как
;
т.е. поскольку foo
ничего не возвращает, я должен иметь возможность заменить его ничем, не меняя смысла программы.
Таким образом, ясно, что ни printf
, ни foo
не являются референциально прозрачными и, следовательно, ни один из них не является чистым. На самом деле функция void
никогда не может быть ссылочно прозрачной, если только она не является неоперативной.
Я считаю, что с этим определением гораздо проще обращаться, чем с тем, которое вы дали. Это также позволяет вам применять его с любой степенью детализации: вы можете применять его к отдельным выражениям, к функциям, ко всем программам. Это позволяет вам, например, говорить о такой функции:
func fib(n):
return memo[n] if memo.has_key?(n)
return 1 if n <= 1
return memo[n] = fib(n-1) + fib(n-2)
Мы можем проанализировать выражения, из которых состоит функция, и легко сделать вывод, что они не являются ссылочно прозрачными и, следовательно, нечистыми, поскольку они используют изменяемую структуру данных, а именно массив memo
. Однако мы также можем посмотреть на функцию и увидеть, что она является ссылочно прозрачной и, следовательно, чистой. Иногда это называется внешняя чистота, то есть функция, которая кажется чистой для внешнего мира, но реализуется нечистой внутри.
Такие функции по-прежнему полезны, потому что в то время как примесь заражает все вокруг себя, внешний чистый интерфейс выстраивает своего рода «барьер чистоты», где примесь заражает только три строки функции, но не просачивается в остальную часть программы. . Эти три строки гораздо легче проанализировать на правильность, чем всю программу.
person
Jörg W Mittag
schedule
05.03.2019