Так как чистота входного параметра неизвестна до времени выполнения, считается ли функция немедленно нечистой, если она принимает функцию в качестве входного параметра?
Связано: если функция применяет чистую функцию, которая определена вне функции, но не передана в качестве параметра, будет ли она все еще чистой, если она удовлетворяет критериям отсутствия побочных эффектов, а результат зависит исключительно от ввода?
Для контекста я пишу функциональный код на JavaScript.
functional-programming
pure-function
Dancrumb
источник
источник
foo = function(function bar){ print(bar.toString()) }
foo = function(function bar) { return 3; }
является чистым, и принимает функцию в качестве аргумента.toString()
(то есть тот, который вы найдете в объекте Java).Ответы:
Пока все значения, используемые в функции, определяются исключительно ее параметрами, это чистая функция.
Фасет, который выводится одинаково каждый раз для одного и того же ввода, определяется тем, являются ли параметры чистыми. Если вы предполагаете, что параметры (например, аргумент функции) также являются чистыми, то это чисто.
В таком языке, как Javascript, где чистота не обеспечивается, это означает, что можно заставить иначе чистую функцию иметь нечистое поведение, вызывая нечистую функцию, переданную в качестве параметра.
Это фактически означает, что для языков, которые не обеспечивают чистоту (то есть почти для всех), невозможно определить чистую функцию, которая вызывает функции, переданные в качестве аргументов. Все еще полезно писать их как можно более чистыми и рассуждать о них как о чистых функциях, но вы должны проявлять осторожность, потому что предположение, что это чисто, будет нарушено, если вы передадите неверные аргументы.
По моему опыту на практике это обычно не имеет большого значения - я нахожу редким использование нечистых функций в качестве аргументов функций для чистых функций.
источник
areaOfCircle r => Math.Pi * r * r
, будет ли онаareaOfCircle
не чистой, поскольку она не просто использует параметры?f(f2)
которая вызываетf2
, не полагается на то, на чтоf2
полагается. Функция, которая может вызывать произвольные переданные функции, не является чистой.function compose(f, g) {return function h(x) {return f(g(x));};}
, что чисто, несмотря на то, что функции принимают в качестве аргументов.find
подпрограмме нечистый предикат, который возвращает «true» для третьего соответствующего элемента, с которым она сталкивается, или какую-то подобную чепуху.Контрпример:
Неважно,
other_function
является ли это чистая функция, нечистая функция или не функция вообще.pure
Функция является чистой.Другой контрпример:
Эта функция чиста, даже если
x
это нечистая функция.identity(impure_function)
всегда будет возвращатьсяimpure_function
, независимо от того, сколько раз вы повторите вызов. Не имеет значения,identity(impure_function)()
всегда ли возвращает одно и то же; функция , в возвращаемом значении возвращаемого значения в не влияет на его чистоту.В общем, если функция может вызвать функцию, переданную в качестве аргумента, она не является чистой. Например, функция
function call(f) {f();}
не является чистой, потому что, хотя она не упоминает ни о каком глобальном или изменяемом состоянии, онаf
может вызыватьalert
видимые побочные эффекты.Если функция принимает функции в качестве аргументов, но не вызывает их или не вызывает их, то она может быть чистой. Это может все еще быть нечистым, если он делает какую-то другую нечистую вещь. Например,
function f(ignored_function) {alert('This isn't pure.');}
нечист, даже если он никогда не звонитignored_function
.источник
Технически, да, если только в вашем языке нет способа гарантировать, что функция ввода также чиста.
Да. Итак, давайте сосредоточимся на том, что здесь важно. Вызов функции чистый или нет, сам по себе бесполезен. Чистые функции полезны, потому что создание одного и того же вывода для любого ввода, не зависящего от состояния или наличия побочных эффектов, является очень полезным набором свойств. Это означает, что после запуска вашей функции вы можете «запомнить» ответ для этого ввода, и он всегда будет верным. Вам также не нужно снова запускать функцию, чтобы генерировать побочные эффекты.И вы можете запустить эту функцию параллельно (или не по порядку) с другими функциями и знать, что у них не будет никаких скрытых взаимодействий, которые ведут себя плохо.
Эти полезные свойства сохраняются, если функция использует для своей работы другие функции только для чтения, независимо от того, как она на них ссылается.
источник
Как сказал Теластин: Технически, да, если только в вашем языке нет способа гарантировать, что функция ввода также чиста.
Это не гипотетически, есть действительно хорошие способы гарантировать это. По крайней мере, на строго типизированном языке.
Такая чистая функция, которую вы написали бы в JavaScript как
можно перевести непосредственно на Haskell:
Теперь в JavaScript вы можете делать такие злые вещи, как
Это невозможно в Хаскеле . Причина в том, что что-то вроде побочного эффекта
console.log()
всегда должно иметь тип результатаIO something
, а не толькоsomething
один.Для этого выражения для проверки типов нам нужно дать
foo
сигнатуру типаНо оказывается, что я больше не могу это реализовать: поскольку функция аргумента имеет
IO
свой результат, я не могу использовать его внутриfoo
.Единственный способ использовать
IO
действие вfoo
том случае, если результатfoo
имеетIO Int
сам тип :Но на данный момент из подписи ясно,
foo
что это не чистая функция.источник
unsafeIO
:-)IO
. Кстати, его также можно использовать, чтобы вызвать хаос, скрывая побочные эффекты в «чистой» функции, но это действительно небезопасно в Haskell, поскольку на самом деле нет надежного способа указать порядок оценки чистых функций.unsafeIO
; это последний спасательный люк, который обходит гарантии системы типов, и, следовательно, ваш не очень хороший момент.Нет это не так.
Если переданная функция является нечистой И ваша функция вызывает переданную функцию, то ваша функция будет считаться нечистой.
Отношение чистый / нечистый немного похоже на синхронизацию / асинхронность в JS. Вы можете свободно использовать чистый код из нечистых, но не наоборот.
источник