Является ли функция, которая вызывает Math.random (), чистой?

Является ли следующая функция чистой?

function test(min,max) {
   return  Math.random() * (max - min) + min;
}

Насколько я понимаю, чистая функция соответствует следующим условиям:

  1. Возвращает значение, вычисленное по параметрам
  2. Он не выполняет никакой работы, кроме вычисления возвращаемого значения

Если это определение верно, моя функция - чистая функция? Или мое понимание того, что определяет чистую функцию, неверно?

108 голосов | спросил Kiwi Rupela 31 +03002017-10-31T15:14:43+03:00312017bEurope/MoscowTue, 31 Oct 2017 15:14:43 +0300 2017, 15:14:43

8 ответов


0

Нет, это не так. При одинаковом входе эта функция будет возвращать разные значения. И тогда вы не сможете создать «таблицу», которая отображает входные и выходные данные.

Из статьи Википедии для функции Pure :

  

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

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

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

function test(random, min, max) {
   return random * (max - min) + min;
}

и затем назовите его следующим образом (например, с 2 и 5 как min и max):

test( Math.random(), 2, 5)
ответил Christian Benseler 31 +03002017-10-31T15:16:40+03:00312017bEurope/MoscowTue, 31 Oct 2017 15:16:40 +0300 2017, 15:16:40
0

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

Используя Math.random, вы определяете его значение чем-то отличным от входных значений. Это не чистая функция.

источник

ответил TKoL 31 +03002017-10-31T15:17:12+03:00312017bEurope/MoscowTue, 31 Oct 2017 15:17:12 +0300 2017, 15:17:12
0

Нет, это не чистая функция, потому что ее вывод не зависит только от предоставленного ввода (Math.random () может выводить любое значение), в то время как чистые функции всегда должны выводить одинаковое значение для одинаковых входов.

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

P.S для меня, по крайней мере, и для многих других, редукс сделал популярным термин pure function . Прямо из документов с избыточным количеством :

  

То, что вы никогда не должны делать внутри редуктора:

     
  • Мутируйте его аргументы;

  •   
  • Выполнение побочных эффектов, таких как вызовы API и переходы маршрутизации;

  •   
  • Вызовите не чистые функции, например, Date.now () или Math.random ().

  •   
ответил Shubhnik Singh 31 +03002017-10-31T15:35:16+03:00312017bEurope/MoscowTue, 31 Oct 2017 15:35:16 +0300 2017, 15:35:16
0

С математической точки зрения ваша подпись не

test: <number, number> -> <number>

, но

test: <environment, number, number> -> <environment, number>

где environment может предоставить результаты Math.random(). А на самом деле генерация случайного значения изменяет среду как побочный эффект, поэтому вы также возвращаете новую среду, которая не равна первой!

Другими словами, если вам нужен какой-либо ввод, не основанный на начальных аргументах (часть <number, number>), то вы должны быть обеспечены средой выполнения (которая в этом примере предоставляет состояние для Math). То же самое относится и к другим вещам, упомянутым в других ответах, таких как ввод-вывод или тому подобное.


В качестве аналогии вы также можете заметить, что именно так можно представить объектно-ориентированное программирование - если мы скажем, например,

SomeClass something
T result = something.foo(x, y)

тогда на самом деле мы используем

foo: <something: SomeClass, x: Object, y: Object> -> <SomeClass, T>

с объектом, для которого вызывается его метод, являющимся частью среды. И почему часть SomeClass результата? Потому что состояние something также могло измениться!

ответил Adam Kotwasinski 31 +03002017-10-31T20:46:08+03:00312017bEurope/MoscowTue, 31 Oct 2017 20:46:08 +0300 2017, 20:46:08
0

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

https://github.com/MostlyAdequate/mostly Достаточный-гид /блобо /ведущий /ch3.md

ответил Rishabh Mishra 31 +03002017-10-31T15:18:51+03:00312017bEurope/MoscowTue, 31 Oct 2017 15:18:51 +0300 2017, 15:18:51
0

В дополнение к другим ответам, которые правильно указывают на то, что эта функция недетерминирована, она также имеет побочный эффект: она вызовет будущие вызовы math.random(), чтобы вернуть другой ответ. А генератор случайных чисел, у которого нет этого свойства, обычно выполняет некоторый ввод-вывод, например, для чтения со случайного устройства, предоставляемого ОС. Любой является верботеном для чистой функции.

ответил Davislor 31 +03002017-10-31T19:17:19+03:00312017bEurope/MoscowTue, 31 Oct 2017 19:17:19 +0300 2017, 19:17:19
0

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

function test(min, max, generator) {
  return  generator() * (max - min) + min;
}

Теперь вы можете смоделировать генератор и правильно протестировать ваш код:

const result = test(1, 2, () => 3);
result == 4 //always true

А в вашем "производственном" коде:

const result = test(1, 2, Math.random);
ответил Héctor 31 +03002017-10-31T15:27:24+03:00312017bEurope/MoscowTue, 31 Oct 2017 15:27:24 +0300 2017, 15:27:24
0

Вы согласны со следующим:

return ("" + test(0,1)) + test(0,1);

быть эквивалентным

var temp = test(0, 1);
return ("" + temp) + temp;

?

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

У меня есть практический опыт с этим. SQL-сервер разрешил getdate() и newid() in " чисто "функции и оптимизатор будет дедуплицировать вызовы по желанию. Иногда это делает что-то глупое.

ответил Joshua 3 52017vEurope/Moscow11bEurope/MoscowFri, 03 Nov 2017 04:59:17 +0300 2017, 04:59:17

Похожие вопросы

Популярные теги

security × 330linux × 316macos × 2827 × 268performance × 244command-line × 241sql-server × 235joomla-3.x × 222java × 189c++ × 186windows × 180cisco × 168bash × 158c# × 142gmail × 139arduino-uno × 139javascript × 134ssh × 133seo × 132mysql × 132