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



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



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


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




  1. возвращает значение, вычисленное из параметров

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


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

568   9  

9 ответов:

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

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

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

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

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

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

а потом назовем это так (например, с 2 и 5 Как мин и Макс):

test( Math.random(), 2, 5)

самый простой ответ на ваш вопрос заключается в том, что Math.random() нарушает правило № 2.

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

как и все генераторы псевдослучайных чисел, Math.random() начинается со значения "seed". Затем он использует это значение в качестве отправной точки для сети низкого уровня бит манипуляции или другие операции, которые приводят к непредсказуемым (но не совсем случайные) вывода.

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

реализация выбирает начальное семя для алгоритма генерации случайных чисел; он не может быть выбран или сброшен пользователем.

вот почему эта функция не является чистой: JavaScript по существу использует неявный параметр функции, который вы не можете контролировать. Он считывает этот параметр из данных, вычисленных и сохраненных в другом месте, и поэтому нарушает правило № 2 в вашем определении.

если вы хотите сделать это чистой функцией, вы можете использовать один из альтернативных генераторов случайных чисел, описанных здесь. Вызовите этот генератор seedable_random. Она принимает один параметр (семя) и возвращает "случайное" число. Из конечно, это число на самом деле не случайно; оно однозначно определяется семенем. Вот почему это чистая функция. Выход seedable_random является только "случайным" в том смысле, что прогнозирование выхода на основе ввода трудно.

чистая версия этой функции должна была бы принять три параметры:

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

для любой тройки (min, max, seed) параметры, это всегда будет возвращать один и тот же результат.

обратите внимание, что если вы хотел выход seedable_random на истинно random, вам нужно будет найти способ рандомизации семян! И какая бы стратегия вы ни использовали, она неизбежно будет нечистой, потому что она потребует от вас сбора информации из источника, находящегося вне вашей функции. Как mtraceur и jpmc26 напомните мне, это включает в себя все физические подходы: аппаратные генераторы случайных чисел,веб-камеры с крышки объектива,атмосферные помехи коллекционеры -- даже лавовые лампы. Все они включают использование данных, вычисленных и сохраненных вне функции.

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

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

источник

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

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

P. S для меня, по крайней мере, и для многих других, redux сделал термин чисто функция популярные. прямо из redux docs:

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

  • мутировать своих доводов;

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

  • вызов не чистых функций, например Date.теперь () или математика.случайный.)(

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

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

но

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

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

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


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

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

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

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

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

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

https://github.com/MostlyAdequate/mostly-adequate-guide/blob/master/ch3.md

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

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

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);

Вы были бы в порядке со следующим:

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

эквивалентна

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

?

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

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

Comments

    Ничего не найдено.