Из Википедии, бесплатной энциклопедии
Перейти к навигации Перейти к поиску

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

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

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

Примеры [ править ]

Чистые функции [ править ]

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

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

Нечистые функции [ править ]

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

  • из-за изменения возвращаемого значения со статической переменной
int  f ()  {  статический  int  x  =  0 ;  ++ x ;  вернуть  x ; }
  • из-за изменения возвращаемого значения с нелокальной переменной
int  f ()  {  вернуть  х ; }
По той же причине, например, функция библиотеки C ++ sin()не является чистой, поскольку ее результат зависит от режима округления IEEE, который можно изменить во время выполнения.
  • из-за изменения возвращаемого значения с изменяемым ссылочным аргументом
int  f ( int *  x )  {  return  * x ; }
  • из-за изменения возвращаемого значения с входным потоком
int  f ()  {  int  x  =  0 ;  std :: cin  >>  x ;  вернуть  x ; }

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

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

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

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

Ввод / вывод в чистых функциях [ править ]

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

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

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

Оптимизация компилятора [ править ]

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

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

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

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

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

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

См. Также [ править ]

  • Выполнение функции во время компиляции: оценка чистых функций во время компиляции
  • Детерминированный алгоритм
  • Чисто функциональная структура данных
  • Лямбда-исчисление
  • Побочный эффект (информатика)
  • Чистая процедура
  • Идемпотентность
  • ключевое слово pure в Фортране, аннотирующее чистые функции
  • Ключевое слово constexpr в C ++, аннотирующее чистые функции, которые можно использовать во время компиляции

Ссылки [ править ]

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

Внешние ссылки [ править ]

  • Чистый атрибут в Фортране
  • Атрибут constexpr в C ++
  • Чистый атрибут на языке D