Концепция чистых функций, кажется, имеет значение только в... функциональных языках? Поправьте меня если я ошибаюсь. Ссылка на Википедию, которую вы предоставляете, содержит две ссылки вверху, одна из которых Практически адекватное руководство профессора Фрисби по функциональному программированию. Если существует несколько различных квалификаций для чистой функции, в том числе:
не имеет наблюдаемого побочного эффекта
Это важно, потому что одна из вещей, которые мы можем сделать с чистой функцией (в отличие от нечистой функции), — это мемоизация (по ссылке выше) или кэширование ввода/вывода. Чистые функции также проверяемы, разумны и самодокументируемы.
Я предполагаю, что запоминание имеет значение для компилятора, поэтому вопрос о том, является ли функция "чистой" может считаться эквивалентным вопросу о том, может ли компилятор запомнить функцию. Кажется, что концепция локальной переменной static
, которую никакая другая часть кода не затрагивает, — это просто плохой код, и компилятор должен выдать предупреждение об этом. Но должен ли компилятор оптимизировать его? И должен ли компилятор попытаться выяснить, действительно ли любая заданная static
локальная переменная не имеет побочных эффектов?
Кажется, что проще спроектировать компилятор так, чтобы он всегда помечал функцию как нечистую, если у нее есть static
локальный, вместо того, чтобы писать логику, чтобы халтурить и думать о том, запоминаема функция или нет. Видишь местного static
? Бум: больше не чистый.
Так что с точки зрения компилятора это нечисто.
А как насчет других свойств чистой функции?
проверяемый, разумный и самодокументируемый
Тесты обычно пишет человек, поэтому я бы сказал, что эту функцию можно тестировать. Хотя некоторые автоматизированные программы для написания тестов могут снова увидеть, что они не запоминаются, и просто полностью игнорировать написание тестов для них. Это гипотетическое программное обеспечение может просто пропустить что-либо с локальными static
. Опять же, гипотетически.
Является ли код разумным? Конечно нет. Хотя я не уверен, насколько это важно. Он ничего не делает. Это затрудняет понимание. («Почему Боб написал функцию таким образом? Это ситуация Magic/More Magic?»).
Является ли код самодокументируемым? Опять же, я бы сказал, что нет. Но опять же, это вырожденный пример кода.
Я думаю, что самый большой аргумент против того, что это считается чистой функцией, заключается в том, что компилятор функционального языка был бы совершенно разумным, если бы он просто предположил, что он не чистый.
Я думаю, что самый большой аргумент в пользу того, что это считается чистой функцией, заключается в том, что мы можем посмотреть на нее собственными глазами и увидеть, что внешнее поведение явно отсутствует. Не обращайте внимания на то, что подписанное переполнение не определено. Замените его типом данных, который определил переполнение и является атомарным. Что ж, теперь нет неопределенного поведения, но оно по-прежнему выглядит странно.
«В заключение, мне все равно, чистый он или нет».
Позвольте мне перефразировать мой предыдущий (выше) вывод.
Я склонен просто сканировать функцию на предмет любой мутации статических переменных и заканчивать работу. Бум, уже не чисто.
Можно ли считать функцию чистой, если мы действительно о ней подумаем? Конечно. Но в чем смысл? Если необходимо изменить определение чистой функции, приведите доводы в пользу этого. Похоже, вы думаете, что это чистая функция. Это нормально, я вижу в этом достоинства. Я также вижу достоинства в том, чтобы считать это нечистой функцией.
Несмотря на то, что это не ответ, это действительно зависит от того, для чего вы используете определение чистого. Если он пишет компилятор? Вероятно, вы захотите использовать более консервативное определение чистоты, допускающее ложные срабатывания и исключающее эту функцию. Чтобы произвести впечатление на группу второкурсников компьютерных наук, слушая Zep? Выберите определение, которое признает, что это не имеет побочных эффектов, и закройте его.
person
JohnFilleau
schedule
05.03.2020
f
приведет к целочисленному переполнению и, следовательно, к неопределенному поведению, если я не ошибаюсь. - person churill   schedule 05.03.2020x
действительно достаточно изолирован, тоf
можно считать чистым. Но обычно это означает, что вам на самом деле не нужна переменная. - person François Andrieux   schedule 05.03.2020f()
, что делает ее недоступной для наблюдения какой-либо другой функцией (поэтому они не могут изменить свое поведение на основе значенияx
). Если этого никто не видит, значит, этого не существует. Если это плохо, то почему локальные переменные (выделенные в стеке) не нарушают чистоты? Локальные переменные также являются глобальными переменными с ограниченной областью действия в некотором смысле. - person toriningen   schedule 05.03.2020⊥
). Например, для какой-то чистой функции может быть выделен стек настолько большой, что он испортит стек другой функции, не нарушая его чистоты. - person toriningen   schedule 05.03.2020x
, он никогда не раскрывается и не доступен для другого кода. Если каким-то образом это было доступно, у вас были бы проблемы с запуском этого многопоточного,x++
не атомарного, что означает, что он, возможно, далек от чисто функционального. Одним из способов определения чистых функций является то, что они не обмениваются данными между вызовами. - person tadman   schedule 05.03.2020f()
, тоf()
не был бы чистым со 100% уверенностью, потому что другие функции могут теоретически изменить свое поведение на основе значенияx
, даже если они не. Но так как он недоступен, и неважно, чтоf()
делает сx
(вычисление1000*x
-й цифры числа π может быть многопоточным?), пока его нигде не видно, он чистый, не так ли? - person toriningen   schedule 05.03.2020x
только манипулируется и никогда не используется, то он является кандидатом на удаление достаточно умным оптимизирующим компилятором. Вопрос здесь в том, учитывается ли когда-либоx
в каких-либо других вычислениях? а если нет тоx
можно смело удалять. Если его можно удалить, то эту функцию можно сделать чисто функциональной, но для этого потребуется исключить этот термин. - person tadman   schedule 05.03.2020f()
, потому что любой чистый_ -> unit
неотличим от простого константногоunit
. - person toriningen   schedule 05.03.2020clang
, чтобы увидеть, что они делают с включенной полной оптимизацией, а также что другие функциональные языки, такие как Haskell или Erlang, делают с той же функцией. - person tadman   schedule 05.03.2020sin()
, вроде бы чистыми. Нереференциально прозрачные функции нельзя считать чистыми. - person toriningen   schedule 05.03.2020