Чи вважається функція, яка отримує значення від іншої функції, чистою?


9

Я намагаюся розібратися з способом обробки значень змінних за замовчуванням при створенні функцій без побічних ефектів і закінчився наступним:

function getDefaultSeparator() {
    return ':';
}

function process(input, separator) {
    var separator = separator || getDefaultSeparator();

    // Use separator in some logic

    return output;
}

Розділювач за замовчуванням буде використовуватися в інших функціях, і я хочу його визначити лише в одному місці.

Якщо це чиста функція, чим відрізняється просто використання глобальної константи DEFAULT_SEPARATOR?


5
Немає ніякої суттєвої різниці, якщо ви не плануєте використовувати функцію як заповнювач для певної логіки, яку слід додати пізніше.
Роберт Харві

3
Можливий дублікат Чи функція негайно нечиста, якщо вона приймає функцію як параметр? . Питання не є точним дублікатом, але відповідь має бути однаковою. ("Це залежить від чистоти іншої функції.")
jpmc26

1
Використання глобальної константи не робить функцію нечистою. Використовуючи глобальне значення , що ви припускаєте постійно робить.
чепнер

До речі, ви можете каррі process(із зворотним порядком параметрів), а потім спеціалізувати функцію curryvar processDefault = process(":")
bob

Відповіді:


22

Чи вважається функція, яка отримує значення від іншої функції, чистою?

Це залежить від того, що робить інша функція, і що виконує функція виклику. Домішки заразні, чистота - ні.

Виклик чистої функції не змінює чистоту функції виклику. Виклик нечистої функції автоматично робить функцію виклику також нечистою.

Отже, у вашому прикладі це залежить від чистоти частини, яку ви залишили: якщо це чисто, то вся функція є чистою.

Якщо це чиста функція, чим відрізняється просто використання глобальної константи DEFAULT_SEPARATOR?

Нічого. Функція, яка завжди повертає однакове значення, не відрізняється від константи. Насправді саме так моделюють константи в λ-обчисленні.


2
"Виклик нечистої функції автоматично робить функцію виклику нечистою також" Ви впевнені в цьому? AFAICS, викликаючи нечисту функцію, автоматично не робить абонента нечистим, хоча це може зробити.
Дедуплікатор

2
@ Дедуплікатор: залежить від того, скільки статичного аналізу ви можете (турбуєте). Звичайно, якщо є функція, funcяка має побічні ефекти, коли ви переходите в 0, але не тоді, коли ви проходите через 1, то ви можете з розумом сказати, що хоча funcсама "нечиста", функція називає її як func(1)(і ігноруючи повернене значення, давайте сказати) не обов’язково нечисто. Виклику funcдостатньо, щоб "попередити" абонента як потенційно нечистого, але порушена функція певним чином може виявитися чистою. Принаймні, у javascript, де pure / нечистий не визначений у мові.
Стів Джессоп

6

Так, це обидві чисті функції (якщо припустимо, що згадана частина також є чистою), оскільки:

  1. Результат залежить лише від параметрів.
  2. Побічних ефектів немає.

Зауважте, що якби getDefaultSeparator()не була чиста функція, то ні одна з них не була process()б чистою.

У Javascript немає значущої різниці між використанням чистої функції або константи, і обидва можуть бути використані чистою функцією, доки можливість Javascript переробляти функції або змінювати значення констант уникає.

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


1

Як кажуть інші, звичайно, це все-таки чиста функція.

Однак поговоримо про проблеми дизайну. Ви маєте право спробувати зробити щось, щоб зберегти код DRY, поставивши значення лише один раз у місці. Крім того, я вважаю, що також слід враховувати рівень зв'язку, який є відповідним.

Використання функції дає вам більшу гнучкість для зміни реалізації, тобто, що підхід до функції пропонує більш зв'язане з'єднання, ніж глобальна змінна.

Питання в тому, потрібен він чи ні?

Якщо споживачі та постачальник перебувають у одному модулі, а постачальник є приватним модулем, важко стверджувати, що цей рівень вільної зв'язку є необхідним через те, що якщо постачальник вимагає оновлення від приватної змінної до а приватний метод, простий рефакторинг в межах модуля може бути застосований до споживачів одночасно. Використання методу / функції, перш ніж вам дійсно потрібно, може потрапити під YAGNI.

Навіть якщо споживачі (постачальники) та постачальник перебувають у різних модулях, все ж модулі розбиті разом (наприклад, ви використовуєте міні-модуль, щоб модулі споживачів і постачальника знаходилися в одному файлі), YAGNI також може застосовуватися.

З іншого боку, якщо, наприклад, виробник перебуває в бібліотеці або пакеті або модулі API, які розроблені окремо від споживачів (ів), то використання функції може бути доречним. У цьому випадку ми повинні дивитися на довговічність API та такі принципи, як OCP.

(З іншого боку, якщо ваш код має значні розміри, я б рекомендував використовувати модулі з полями та методами, а не глобальними змінними та функціями.)

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.