#functional-programming #purely-functional #pure-function
#функциональное программирование #чисто функциональный #чистая функция
Вопрос:
Я узнал, что чистая функция — это функция, которая не изменяет глобальное состояние, точка. Если это верно, функции внутри функций могут изменять состояние внешней функции и при этом оставаться чистыми, правильными?
Пример:
function func1() {
let name = "My Name"
func2()
function func2() {
// alter name here.
}
}
В приведенном выше примере func2
по-прежнему является чистым, потому что оно не использует никакого глобального состояния.
Вот как я вижу, но мои коллеги по работе считают, что func2
это не чисто, и это должно быть записано как:
function func1() {
let name = "My Name"
func2(name)
function func2(name) {
// use name here.
}
}
Что плохо, потому что:
- если v8 не оптимизирует это, процессор выполнит больше инструкций
- затенение — плохая практика
Вопрос в том, что именно является чистой функцией, когда мы говорим о функции внутри функции?
Комментарии:
1. используйте != изменить. О какой из них вы говорите?
2. @Bergi Я хотел бы знать ваши мысли по поводу обеих вещей.
Ответ №1:
Чистота не определена так, чтобы заботиться только о глобальных переменных, она заботится о любых нелокальных переменных (и более), которые не должны быть изменены. Внешняя переменная замыкания по-прежнему считается нелокальной, ей не обязательно быть глобальной.
Так что, если func2
изменения name
, то это нечисто. func1
Становится ли это нечистым из-за этого, зависит от того, учитываете ли вы только внешнюю чистоту — до тех пор, пока name
и func2
остаются локальными внутри функции, она все еще может быть чистой.
Ответ №2:
Чистая функция — это функция, которая отвечает 2 требованиям:
- При одинаковом вводе он всегда будет возвращать один и тот же результат.
- Не вызывает побочных эффектов.
Побочные эффекты можно определить как ‘любое изменение состояния приложения, которое можно наблюдать за пределами вызываемой функции, отличное от ее возвращаемого значения’.
Чтобы быть более конкретным:
-
Функция, которая изменяет что-либо за пределами своей области видимости (даже если это не глобальная область видимости), не является чистой функцией.
-
В вашем примере, если func2 изменяет переменную за пределами своей области видимости, то это не чистая функция:
function func1() {
let name = "My Name"; // <-- the variable is not in the global scope but, in any case, it is outside the scope of func2
func2();
function func2() {
// alter name here.
}
}
Ответ №3:
Я узнал, что чистая функция — это функция, которая не изменяет глобальное состояние, точка.
Ну, это чрезмерно упрощает. Чистая функция должна, во-первых, не иметь побочных эффектов, и, во-вторых, ее результат должен зависеть только от аргументов. Итак, как следствие, нет состояния. Ваше func1
свойство name
подозрительно похоже на состояние. Могу ли я ее изменить? func1()
Даст разные результаты в зависимости от предыдущих вызовов? Нечистое!
Конечно, нечистота func2 не подлежит сомнению. Вы написали «изменяет имя» — ‘name’ находится за пределами его области. Это побочный эффект.
Ответ №4:
Другой пример, который, я думаю, стоит упомянуть, — это следующая чистая функция:
function insert(DB, user) {
return function() {
throwIfUserExists(DB, user);
var savedUser = saveUser(DB, user);
return savedUser;
}
}
Обратите внимание, что при вызове insert
, пока вы продолжаете отправлять одно и то же DB
и user
, вы получите тот же результат, что и функция, возвращающая другую функцию — никакого побочного эффекта не происходит.