Может ли чистая функция вызывать внешнюю функцию?

Может ли чистая функция вызывать внешний метод?

Например:

class Dog {
  function jump(name) {
    return "a dog named " + name + " jumped!"
  }

  function jumpTwice(names) {
    var result = [];
    for (var i = 0; i < 2; i++) {
       result.push(jump(names[i]));
    }
    return result.join("\n");
  }

}

можно ли jumpTwice() считать pure function?


person bbnn    schedule 14.09.2016    source источник


Ответы (3)


Когда ты можешь

Чистая функция f может вызывать любую другую функцию/метод g0...gn. Но g0...gn также должен быть чистым.

Когда ты не можешь

Как только вы получаете чистую функцию f и вызываете нечистую функцию g из f, тогда f уже не является чистой.

person Luca Angeletti    schedule 14.09.2016

Да, это чисто. Он не изменяет какое-либо глобальное состояние и не дает разных результатов для одного и того же ввода.

person Gabriel    schedule 14.09.2016

В конкретном случае вы даете, да. Но то, что у вас есть, это метод, а методы требуют особой осторожности.

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

Недостаточно избегать изменяемых полей — значение в поле неизменяемых полей должно быть известным/предсказуемым. Например, если объект содержит неизменяемое приватное поле, которому при создании объекта присваивается случайное число, любой метод, использующий это значение для вычисления вывода, будет нечистым.

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

ИЗМЕНИТЬ

Было бы полезно сказать, что «побочный эффект» и «чистота» зависят от контекста (как обсуждалось в комментариях). Это то, на что я не совсем четко намекал, используя слова «познаваемый» и «предсказуемый». Обсуждение комментариев иллюстрирует важность знания контекста.

person itsbruce    schedule 14.09.2016
comment
Я не уверен, что вы подразумеваете под познаваемым/предсказуемым. Все поля, которые являются частью объекта, вносят вклад в ввод метода. То, что создание объекта является нечистым (включая случайность), не делает сам метод нечистым. - person Bergi; 15.09.2016
comment
Если метод игнорирует свойства объекта с состоянием, то он предсказуем и чист. Независимо от изменяемых частей ввода, в этом случае вывод предсказуем. - person itsbruce; 15.09.2016
comment
@Bergi, чтобы выбрать самый простой пример, если бы метод класса всегда возвращал значение 1 в любом случае, он был бы чистым, независимо от того, насколько изменчивы поля объекта. - person itsbruce; 15.09.2016
comment
Я пытаюсь подчеркнуть, что не нужно игнорировать изменяемые свойства. Он просто не должен их изменять, он может получить к ним доступ, не делая ничего нечистого. - person Bergi; 15.09.2016
comment
Если он использует изменяемые значения для вычисления вывода, он не является чистым. - person itsbruce; 15.09.2016
comment
Нет, это чисто, так как не мутирует их. Как свойства объекта, для которого вызывается метод, они являются явными входными данными (и постоянными во время выполнения), а не неявным изменяемым состоянием. - person Bergi; 15.09.2016
comment
Я предполагаю, что это разрушает наше определение равенства. Является ли объект в его старом состоянии равным тому же объекту с измененными свойствами? Я говорю нет, и тогда такой изменяемый объект может быть входом чистого метода. - person Bergi; 15.09.2016
comment
Согласно вашему аргументу, создание этого объекта со скрытым случайным полем, а затем вызов метода, который возвращает его значение, является чистой операцией. Что абсолютно не соответствует действительности. Чистота зависит от контекста не в последнюю очередь потому, что побочный эффект можно определить только в четком контексте), но именно поэтому я подчеркивал осторожность с методами класса. - person itsbruce; 15.09.2016
comment
Нет, создание объекта со скрытым случайным полем не является чистым, только вызов метода, который возвращает скрытое поле для объекта. А вместе они явно нечисты. - person Bergi; 15.09.2016
comment
Да, если вы точны в контексте, я согласен с вашей точкой зрения. - person itsbruce; 15.09.2016
comment
В качестве хорошего примера функционального объектно-ориентированного программирования я обычно указываю на класс String в Java. Все методы чистые, и экземпляр никогда не меняет своего состояния. - person Sylwester; 15.09.2016