Кажется, что, читая что-то вроде этой статьи в Википедии о «чистых функциях» , они приводят Today()
в качестве примера нечистую функцию, но она кажется мне довольно чистой. Это потому, что нет формального входного аргумента? Почему фактическое время дня не рассматривается как «входные данные для функции», и в этом случае, если вы дали ему один и тот же ввод, т.е. выполнили today()
два раза в одно и то же время, или переместились назад во времени, чтобы выполнить его снова (возможно, гипотетически: )), на выходе будет одновременно. Today()
никогда не дает вам случайное число. это всегда дает вам время суток.
В статье в Википедии говорится, что «в разное время это приведет к разным результатам», но это все равно, что сказать, что для разных людей x
sin(x)
вы получите разные соотношения. И sin(x)
это их пример чистой функции.
источник
Ответы:
Это связано с тем, что результат зависит от того, что не является входом, а именно от текущего времени.
Потому что вы не передали это как параметр. Если вы передадите его в качестве параметра, функция станет датой в даты, что довольно бесполезно. Весь смысл
Today()
функции в том, чтобы вывести что-то, что зависит от внешнего и постоянно меняющегося значения (времени).Преимущество чистых функций состоит в том, что их поведение абсолютно воспроизводимо и детерминировано, что позволяет легко иметь формальные доказательства и жесткие гарантии. Они всегда делают одно и то же.
Today()
в значительной степени наоборот: он всегда (с учетом детализации времени) делает что-то другое.источник
Today()
),Today()
становится нечистым.Today()
Функция может быть немного глупый пример. Более подходящей может быть какая-тоCount()
функция. При одинаковом количестве предметов для подсчетаCount()
всегда будет возвращаться одно и то же число, но поскольку это выходит за рамкиCount()
его, это нечисто.count()
на большинстве языков программирования определенно чист. У него есть явное входное значение: коллекция, количество которой вы хотите. Не смущайтесь синтаксисом, таким какmyCollection.count()
; это просто сахар дляcount(myCollection)
.sin(x)
всегда будет возвращать одно и то же значение, покаx
остается неизменным.Today()
может возвращать разные результаты с течением времени, потому что это зависит от значений вне вашего контроля . Например, если что-$current_datetime
то, находящееся вне контроля вашей программы, изменит внутреннее состояние системы во время ее работы, оноToday()
внезапно даст другие результаты.источник
Today()
будет возвращать «четверг» в понедельник.Today () - это нечистая функция, потому что ее результат зависит от того, чего вы не даете; в частности, текущее системное время. Следовательно, его результат не является детерминированным, если он основан только на входных данных, предоставленных при вызове.
Чистая функция была бы
int Add(int a, int b) {return a + b;}
. Функция работает исключительно с тем, что ей дано, и не использует никаких других данных внешнего состояния. Естественным результатом этого является то, что вы можетеAdd(2,2)
и получить 4 с этого момента до конца времени. Кроме того, поскольку функция не изменяет никакое внешнее состояние (у нее нет «побочных эффектов»), Add () ing 2 и 2 с этого момента до конца времени не изменит ничего в системе, если только вы не присвойте результат функции переменной или иным образом используйте значение для обновления состояния (которое не является операцией, выполняемой самой функцией). Практически все классические математические операции являются чистыми функциями и могут быть реализованы как таковые.Today (), с другой стороны, может выдавать одно и то же значение при вызове два раза подряд, но не при повторном вызове в течение нескольких дней. Это связано с тем, что он зависит от данных внешнего состояния, которые вы не предоставили в качестве параметра функции. В результате невозможно в рамках программы контролировать результат функции Today (). Он выдаст заданное значение в определенный день и никогда не выдаст это значение в любой другой день, если только вы не измените системные часы компьютера, на котором он запущен (изменение, как правило, происходит за пределами программы).
Нечистая функция не обязательно плохая вещь; нечистые функции требуются, даже на функциональных языках, для взаимодействия с чем-либо, находящимся за пределами программы, например с хранилищами данных, коммуникационными конвейерами, дисплеями пользовательского интерфейса, периферийными устройствами и т. д. Программа, которая не выполняет ничего из этого, является программой. это резко ограничено в его полезности; Я бы даже зашел так далеко, что назвал такую программу тривиальной, так как без каких-либо средств, чтобы принять ввод или какой-либо способ сообщить вам о ее результатах, она могла бы также ничего не делать. Программы, написанные на функциональных языках, могут иметь только входные данные, предоставленные средой выполнения, и создавать выходные данные, сообщаемые среде выполнения, без каких-либо явно определенных нечистых методов, но это потому, что среда выполнения абстрагирует все эти нечистые детали работы в несовершенной компьютерной системе,
Просто очень хорошо знать, какие из функций, которые вы используете, являются чистыми, а какие нет, чтобы вы могли принимать правильные решения о том, как они используются. Нечистые функции, потому что они делают вещи или зависят от вещей, которые не очевидны из их использования, могут вести себя непредсказуемо, учитывая только знание об использовании. Требуются дополнительные знания о назначении функции и, следовательно, о том, что ей нужно от или делает для внешнего состояния, чтобы привести систему, которая использует ее, в согласованное состояние и, таким образом, ожидать детерминированного результата.
источник
Кажется довольно очевидным, что эта функция не проходит первый тест на чистоту, данный в самом начале этой страницы:
Обратите внимание, что поскольку он не принимает аргументов, существует только один возможный набор значений аргумента - пустой набор. И эта функция может и действительно возвращает разные результаты для одного и того же «значения аргумента».
Кроме того, значение результата функции действительно зависит от «скрытой ... состояние , которое может изменяться по мере выполнения программы продолжается». Итак, очередной провал.
источник
() => 1
будет чистой функцией, поскольку она всегда возвращает 1.Today()
может возвращать «понедельник» или «вторник» или почти любое другое значение.Другой способ думать об этом - чистые функции, не зависящие от состояния. Мир обычно считается государством. Вам нужно знать состояние реальности, чтобы знать, какой сегодня день.
Однако вам не нужно знать ничего особенного о состоянии мира, чтобы знать, что это
sin(x)
такое. И когда-либо вызовsin(x)
для данногоx
будет возвращать одно и то же значение.источник
Date(timestamp)
будет чистой функцией. Из-за его идемпотентности. И потому что не будет никакого побочного эффекта.Today()
может варьироваться в зависимости от того, когда вы звоните. Вот что делает его нечистым. Это не идемпотент. У этого нет никакого побочного эффекта, хотя, но это не делает это чистым.источник
Вот небольшой псевдокод, о котором я думаю, когда обсуждаю чистые функции
Если это выполняется бесконечно, и оператор никогда не может вызвать утверждение, это чистая функция. Более того, если у вас есть функция, которая использует аргументы, то небольшая модификация ....
Если вы можете использовать это после каждого присваивания переменной в вашем приложении, и это не меняет результатов в вашем приложении, и оно никогда не может потерпеть неудачу при утверждении, тогда это чистая функция.
источник
Во-первых, не существует функции без аргумента (или массива без индексов или карты без ключей). Это определяющая характеристика функции для сопоставления одного или нескольких значений аргумента с другим значением.
Следовательно,
today
либо не является функцией вообще, следовательно, не является чистой функцией. Или мы можем интерпретировать синтаксиснемного так, что это значит
Например, в Haskell это будет правильно:
потому что есть тип () с одним значением ().
Вопрос только в том, как можно
today
вычислить день недели, если он имеет только ()? Это просто невозможно без чтения системного таймера, напрямую или через нечистые вспомогательные функции.Системный таймер является отличным примером для глобального состояния.
источник
Проблема в
today()
том, что он может давать другой результат, если вызывается два или более раз в функции.Вот пример кода, который может привести к ошибке.
Это возможно в приведенном выше примере. Это второе
if
утверждение не будет выполнено. Даже если первый сделал. Оставив ресурс в плохом состоянии.источник
Чтобы быть чистой функцией, предоставление одинаковых параметров должно давать один и тот же результат каждый раз.
Каждый раз, когда мы вызываем
Today()
, мы предоставляем ему одни и те же параметры (нет), но не обязательно получаем один и тот же результат (понедельник, вторник и т. Д.).источник