stringtranslate.com

Чистая функция

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

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

Примеры

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

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

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

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

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

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

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

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

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

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

Мемоизация

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

Мемоизацию можно выполнить, обернув функцию в другую функцию ( функцию-обертку ). [5]

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

Программа на языке C для кэшированного вычисления факториала ( assert()прерывается с сообщением об ошибке, если ее аргумент ложен; на 32-битной машине значения за пределами этого числа fact(12)в любом случае не могут быть представлены. [ необходима цитата ]

static int fact ( int n ) { return n <= 1 ? 1 : fact ( n -1 ) * n ; } int fact_wrapper ( int n ) { static int cache [ 13 ]; assert ( 0 <= n && n < 13 ); if ( cache [ n ] == 0 ) cache [ n ] = fact ( n ); return cache [ n ]; }                             

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

Функции, которые обладают только указанным выше свойством 2, то есть не имеют побочных эффектов, допускают методы оптимизации компилятора, такие как устранение общих подвыражений и оптимизацию цикла , аналогичную арифметическим операторам. [6] Примером 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 . длина () + a [ i ]; }              

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

Некоторые языки программирования позволяют объявлять чистое свойство функции:

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

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

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

Ссылки

  1. ^ Бартош Милевски (2013). "Основы Haskell". Школа Haskell . FP Complete. Архивировано из оригинала 2016-10-27 . Получено 2018-07-13 .
  2. ^ Брайан Лонсдорф (2015). «В основном адекватное руководство профессора Фрисби по функциональному программированию». GitHub . Получено 20.03.2020 .
  3. ^ Пейтон Джонс, Саймон Л. (2003). Haskell 98 Язык и библиотеки: Пересмотренный отчет (PDF) . Кембридж, Великобритания: Cambridge University Press. стр. 95. ISBN 0-521 826144. Получено 17 июля 2014 г.
  4. ^ Ханус, Майкл. «Карри: интегрированный язык функциональной логики» (PDF) . www-ps.informatik.uni-kiel.de . Институт информатики Университета Христиана Альбрехта в Киле. п. 33. Архивировано из оригинала (PDF) 25 июля 2014 года . Проверено 17 июля 2014 г.
  5. ^ Алей, Р. (2017). Профессиональное функциональное программирование на PHP: стратегии разработки приложений для оптимизации производительности, параллелизма, тестируемости и краткости кода. SpringerLink : Bücher. Apress. стр. 109. ISBN 978-1-4842-2958-3. Получено 2024-02-04 .
  6. ^ "Общие атрибуты функций — использование коллекции компиляторов GNU (GCC)". gcc.gnu.org, коллекция компиляторов GNU . Free Software Foundation, Inc. Получено 28.06.2018 .
  7. ^ Чистый атрибут в Фортране
  8. ^ Чистый атрибут в языке D
  9. ^ "Common Function Attributes". Использование коллекции компиляторов GNU (GCC . Получено 22 июля 2021 г. .
  10. ^ Атрибут constexpr в C++