Могут ли чистые функции читать глобальное состояние? - PullRequest
3 голосов
/ 04 марта 2009

Обратите внимание: под «чистой» функцией я не подразумеваю «чисто виртуальную»
Я имею в виду это

Если функция «читает» некое глобальное состояние, автоматически ли это делает его нечистым? или это зависит от других факторов?

Если он автоматически делает его нечистым, объясните, почему.

Если это зависит от других факторов, объясните, пожалуйста, каковы они.

Ответы [ 4 ]

7 голосов
/ 04 марта 2009

«Чистая» функция - это функция, результат которой зависит только от ее входных аргументов. Если он читает что-то еще, это не чистая функция.

3 голосов
/ 04 марта 2009

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

static int cache[256] = {0};
int compute_something(uint8_t input)
{
    if(cache[input] == 0)
        cache[input] = (perform expensive computation on input that won't return 0);
    return cache[input];
}

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

0 голосов
/ 04 марта 2009

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

0 голосов
/ 04 марта 2009

Чистые функции необходимы для построения чистых выражений. Постоянные выражения являются чистыми по определению.

Итак, если ваше глобальное «состояние» не изменится, у вас все в порядке.

Также см. ссылочная прозрачность :

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

...