Чистая функция - Pure function - Wikipedia

В компьютерное программирование, а чистая функция это функция обладающий следующими свойствами:[1][2]

  1. Его возвращаемое значение то же самое для того же аргументы (без изменений с местными статические переменные, нелокальные переменные, изменчивый ссылочные аргументы или входные потоки из Устройства ввода / вывода ).
  2. Его оценка не имеет побочные эффекты (без изменения локальных статических переменных, нелокальных переменных, изменяемых ссылочных аргументов или потоков ввода-вывода).

Таким образом, чистая функция является вычислительным аналогом математическая функция. Некоторые авторы, особенно из сообщества императивных языков, используют термин «чистый» для всех функций, которые имеют только указанное выше свойство 2.[3][4] (обсуждено ниже ).

Примеры

Чистые функции

Следующие примеры C ++ функции чистые:

  • этаж, возвращая этаж номера;
  • Максимум, возвращая максимум двух значений.
  • функция ж, определяется как
пустота ж() {  статический стандартное::атомный<беззнаковый int> Икс = 0;  ++Икс;}
Хотя этот пример кода выглядит не чистым, на самом деле это так. Значение Икс можно наблюдать только внутри других призывов f (), и, как f () не сообщает о ценности Икс окружающей среде, он неотличим от функции void f () {} это ничего не делает. Обратите внимание, что Икс является std :: atomic так что изменения из нескольких потоков, выполняющих f () одновременно не приводят к гонка данных, у которого есть неопределенное поведение в C и C ++.

Нечистые функции

Следующие функции C ++ являются нечистыми, поскольку у них отсутствует указанное выше свойство 1:

  • из-за вариации возвращаемого значения с нелокальной переменной
int ж() {  возвращаться Икс;}
По той же причине, например, функция библиотеки C ++ грех () не является чистым, так как его результат зависит от Режим округления IEEE который можно изменить во время выполнения.
  • из-за изменения возвращаемого значения с изменяемым ссылочным аргументом
int ж(int* Икс) {  возвращаться *Икс;}
  • из-за несовместимого определенного / неопределенного поведения:
пустота ж() {  статический int Икс = 0;  ++Икс;}
Переполнение целого числа со знаком - это неопределенное поведение согласно спецификации C ++. Кроме того, если f () вызывается одновременно, код показывает гонка данных. Чистые функции могут давать сбой или никогда не возвращаться, но они должны делать это последовательно (для одного и того же входа). Тем не мение, f () может или не может потерпеть неудачу, в зависимости от того, верхняя граница разрешенного подписанный int было достигнуто значение, или произошла гонка данных, или нет.

Следующие функции C ++ являются нечистыми, поскольку у них отсутствует указанное выше свойство 2:

  • из-за мутации локальной статической переменной
пустота ж() {  статический int Икс = 0;  ++Икс;}
  • из-за мутации нелокальной переменной
пустота ж() {  ++Икс;}
  • из-за мутации изменяемого ссылочного аргумента
пустота ж(int* Икс) {  ++*Икс;}
  • из-за мутации выходного потока
пустота ж() {  стандартное::cout << "Привет, мир!" << стандартное::конец;}

Следующие функции C ++ являются нечистыми, поскольку у них отсутствуют оба вышеуказанных свойства 1 и 2:

  • из-за изменения возвращаемого значения с помощью локальной статической переменной и изменения локальной статической переменной
int ж() {  статический int Икс = 0;  ++Икс;  возвращаться Икс;}
  • из-за изменения возвращаемого значения с входным потоком и мутации входного потока
int ж() {  int Икс = 0;  стандартное::cin >> Икс;  возвращаться Икс;}

Ввод / вывод в чистых функциях

Ввод / вывод по своей сути нечист: операции ввода подрывают ссылочная прозрачность, а операции вывода создают побочные эффекты. Тем не менее, есть смысл, в котором функция может выполнять ввод или вывод и при этом оставаться чистой, если последовательность операций на соответствующих устройствах ввода-вывода моделируется явным образом как аргумент и результат, а операции ввода-вывода принимаются в завершиться ошибкой, если входная последовательность не описывает операции, фактически выполненные с момента начала выполнения программы.

Второй пункт гарантирует, что единственная последовательность, используемая в качестве аргумента, должна изменяться при каждом действии ввода-вывода; первый позволяет различным вызовам функции, выполняющей ввод-вывод, возвращать разные результаты из-за изменения аргументов последовательности.[5][6]

В Монада ввода / вывода это идиома программирования обычно используется для ввода-вывода на чистых функциональных языках.

Оптимизация компилятора

Функции, которые имеют только указанное выше свойство 2, позволяют использовать методы оптимизации компилятора, такие как исключение общего подвыражения и оптимизация цикла аналогично арифметическим операторам.[3] Примером C ++ является длина метод, возвращающий размер строки, который зависит от содержимого памяти, на которое указывает строка, поэтому отсутствует указанное выше свойство 1. Тем не менее, в однопоточная среда, следующий код C ++

стандартное::нить s = "Привет, мир!";int а[10] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};int л = 0;за (int я = 0; я < 10; ++я) {  л += s.длина() + а[я];}

можно оптимизировать так, чтобы значение s.length () вычисляется только один раз перед циклом.

В Фортран, то чистый ключевое слово может использоваться для объявления функции, которая не имеет побочных эффектов (т.е. имеет только указанное выше свойство 2).

Модульное тестирование

Поскольку чистые функции имеют одинаковые возвращаемое значение для того же аргументы, они хорошо подходят для модульное тестирование.

Смотрите также

Рекомендации

  1. ^ Бартош Милевски (2013). «Основы Haskell». Школа Хаскелла. FP Complete. Архивировано из оригинал на 2016-10-27. Получено 2018-07-13. Вот основные свойства чистой функции: 1. Функция возвращает точно такой же результат каждый раз, когда она вызывается с одним и тем же набором аргументов. Другими словами, функция не имеет состояния и не может получить доступ к какому-либо внешнему состоянию. Каждый раз, когда вы его называете, он ведет себя как новорожденный ребенок с пустой памятью и незнанием внешнего мира. 2. Функция не имеет побочных эффектов. Один раз вызвать функцию - это то же самое, что вызвать ее дважды и отбросить результат первого вызова.
  2. ^ Брайан Лонсдорф (2015). "Практически адекватное руководство профессора Фрисби по функциональному программированию". GitHub. Получено 2020-03-20. Чистая функция - это функция, которая при одном и том же вводе всегда будет возвращать один и тот же вывод и не имеет наблюдаемых побочных эффектов.
  3. ^ а б "Руководство GCC 8.1". GCC, Коллекция компиляторов GNU. Фонд свободного программного обеспечения, Inc. 2018. Получено 2018-06-28.
  4. ^ Возможности языка Fortran 95 # Чистые процедуры
  5. ^ Пейтон Джонс, Саймон Л. (2003). Язык и библиотеки Haskell 98: обновленный отчет (PDF). Кембридж, Соединенное Королевство: Издательство Кембриджского университета. п. 95. ISBN  0-521 826144. Получено 17 июля 2014.
  6. ^ Ханус, Майкл. «Карри: интегрированный функциональный логический язык» (PDF). www-ps.informatik.uni-kiel.de. Institut für Informatik, Christian-Albrechts-Universität zu Kiel. п. 33. Архивировано с оригинал (PDF) 25 июля 2014 г.. Получено 17 июля 2014.

внешняя ссылка