Що таке термін для функції, який при повторному виклику має той же ефект, що і один раз?


96

(Припускаючи однопотокове середовище)

Функція, яка відповідає цьому критерію:

bool MyClass::is_initialized = false;

void MyClass::lazy_initialize()
{
    if (!is_initialized)
    {
        initialize(); //Should not be called multiple times
        is_initialized = true;
    }
}

По суті, я можу викликати цю функцію кілька разів і не турбуватися про її ініціалізацію MyClassкілька разів

Функцією, яка не відповідає цьому критерію, може бути:

Foo* MyClass::ptr = NULL;

void initialize()
{
    ptr = new Foo();
}

initialize()Багаторазовий дзвінок призведе до витоку пам'яті

Мотивація

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


67
Близьким виборцям: хоча це правда, що 99,999% (приблизна оцінка) усіх питань, що стосуються імені, є поза темою, оскільки вони не мають єдиної, правильної, однозначної, об'єктивної відповіді та іменування є чисто суб'єктивним і на основі думок, це один робить є один, правильний, однозначний, об'єктивну відповідь, який був даний самим ОП.
Йорг W Міттаг

30
Виклик його кілька разів робить мати ефект, так як там може бути інший код , який змінив «вар» між ними.
RemcoGerlich

7
Чому було задано це запитання, якщо ОП знала відповідь на момент запитання ? Чи є якась причина, крім реп / точок / побудови карми?
dotancohen

13
@dotancohen Q / Стиль самовідповіді - одна з ключових концепцій StackExchange.
glglgl

17
@glglgl: Я погоджуюся, для питань із повагою . Яку заслугу має це питання? Я серйозно занепокоєний тим, що ми почнемо отримувати кожне запитання CS 101, яке задається і негайно відповідає ОП, кожен запитуваний термін CS і негайно визначається ОП, а всі плюси та мінуси кожного алгоритму, які негайно задаються питанням, негайно відповідають ОП ( не обов'язково це ОП). Це той сайт, яким ми хочемо бути softwareengineering.SE?
dotancohen

Відповіді:


244

Цей тип функції / операції називається Idempotent

Idempotence (Великобританія: / ˌɪdɛmˈpoʊtəns /, [1] US: / ˌaɪdəm - /) [2] є властивістю певних операцій з математики та інформатики, за допомогою яких їх можна застосовувати кілька разів, не змінюючи результат за межі початкового застосування.

У математиці це означає, що якщо f ідентичне, f ( f (x)) = f (x), що є тим же, що говорити ff = f .

У інформатиці це означає, що якщо f(x);вона безсильна, f(x);це те саме, що f(x); f(x);.

Примітка. Ці значення здаються різними, але під денотаційною семантикою стану слово "ідемпотент" насправді має однакове точне значення і в математиці, і в інформатиці.


Коментарі не для розширеного обговорення; ця розмова переміщена до чату .
maple_shaft

51

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

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

Ви, швидше за все, хочете вказати, що ви хочете чисту функцію. Прикладом чистої функції може бути такий:

int func1(int var)
{
    return var + 1;
}

Більше читання можна знайти в статті Вікіпедії «Чиста функція» .


37
Я думаю, що ваше визначення idempotency занадто вузьке, або, кажучи іншим способом, ви використовуєте математичне визначення idempotency, а не програмування. Наприклад, методи HTTP PUTі DELETEHTTP називаються ідентично потужними саме тому, що виконання їх побічних ефектів багаторазово має той же ефект, що і їх виконання лише один раз. Ви говорите "idempotency означає f∘f = f", тоді як під програмуванням ми маємо на увазі "виконання fмає той самий ефект, як і виконання f; f". Зауважте, що ви можете легко перетворити друге значення в перше, додавши параметр "world".
Йорг W Міттаг

23
@Neil "Ідемпотенція - це строго математичний термін". Ні, це не так, його також використовують в мережевих і клієнтських серверах / комунікації / розподілених системах і описано так, як описує JörgWMittag. Це корисна концепція, оскільки вона дозволяє декілька запитів до сервера / клієнта з однією операцією / повідомленням, не змінюючи те, що ставило це оригінальне повідомлення. Це корисно, коли ви маєте ненадійний зв’язок, і вам потрібно повторити команду, оскільки або повідомлення клієнта було відхилено, або відповідь сервера була.
опа

7
Вам слід детальніше розповісти про різницю між чистим і безсильним. Ваш приклад func1 не є ідентичним, оскільки func1(1) != func1(func1(1)).
Тезра

5
Чистота і безсилля відрізняються. Чиста функція не повинна бути ідентичною у математичному сенсі (вона, очевидно, ідпотентована з точки зору побічних ефектів, оскільки її немає). Функція Idempotent (в розумінні програмування) не повинна бути чистою, як це, наприклад, дано ОП. Крім того, як згадувалося в режимі opa, idempotence - це корисна властивість із суворо іншим використанням, ніж чистота. Визначення чистоти як "безсильної і без побічних ефектів" є помилковим або, принаймні, оманливим, зворотним.
Frax

5
У контексті програмування немає "побічних ефектів", але якщо ви розширите визначення, щоб включити це, то idempotent функція і чиста функція означали б те саме. Ні, вони взагалі не означали б те саме. Ідемпотентна, не чисто: void f(int var) { someGlobalVariable = var; }. Чистий, не тотожні: int func1(int var) { return var + 1; }.
JLRishe

6

Термін - Idempotence . Зауважте нижче, що існує чітка різниця між функцією Idempotent (Викликається рекурсивно на собі; Другий блок коду та Математичне визначення) та функціональною ідентифікацією (Викликається повторно з одним і тим же входом послідовно; Перший блок коду та часто термін, що означає в програмуванні).

У послідовній композиції f, як називається, функція f з побічними ефектами є ідентичною. f, якщо при виклику двічі з однаковим списком аргументів другий виклик не має побічних ефектів і повертає те саме значення, що і перший дзвінок [потрібне цитування] (якщо припустити, що між кінцем першого виклику та початком не було викликано інших процедур другого дзвінка).

Наприклад, врахуйте наступний код Python:

x = 0

def setx(n):
    global x
    x = n

setx(5)
setx(5)

Тут setx ідентичний, оскільки другий виклик setx (з тим же аргументом) не змінює видимий програмний стан: x у першому дзвінку вже було встановлено на 5, а в другому виклику знову встановлюється на 5, таким чином зберігаючи однакове значення. Зауважимо, що це відрізняється від безсилля в складі функції f function f. Наприклад, абсолютне значення є idempotent за функцією складу:

def abs(n):
    if n < 0:
        return -n
    else:
        return n

abs(-5) == abs(abs(-5)) == abs(5) == 5

3

У фізиці я чув це, як це називається проекцією :

проекція є лінійним перетворенням Р з векторного простору в себе, що Р 2 = Р . Тобто щоразу, коли P застосовується двічі до будь-якого значення, він дає той самий результат, як якщо б він був застосований один раз (idempotent).

Графічно це має сенс, якщо ви подивитеся на мультфільм векторної проекції :

введіть тут опис зображення

На малюнку a 1 - це проекція a на b , що схоже на перше застосування вашої функції. Наступні проекції в 1 на с б дають однаковий результат 1 . Іншими словами, коли ви викликаєте проекцію неодноразово, це має такий же ефект, як і виклик її один раз.

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


2
Це справді приємний конкретний приклад того, як ідентифікаційна функція може бути візуалізована (математично, і особливо у векторній геометрії / лінійному полі алгебри). Хоча "idempotence" програмної функції - це дуже близьке поняття, я не думаю, що розробники / комп'ютерні працівники часто використовують слово "проекція" в цьому контексті ("функція проекції" в інженерії програмного забезпечення швидше посилається на функцію, яка приймає об'єкт і повертає новий об’єкт, отриманий від нього, наприклад, властивість цього об'єкта, наприклад)
Pac0,

2
@ Pac0 О, добре. Я працюю на межі між наукою та програмуванням, і не розумів, що це слово вже перевантажене. Я можу придумати кілька надуманих прикладів на роботі, де я би використовував цю термінологію, але я, правда, щодня працюю з людьми, які бажають миритися з науковим жаргоном :-)
user1717828

3

Це алгоритм детермінованості, оскільки, якщо вводити один і той же вхід (в даному випадку немає вводу), він завжди буде отримувати один і той же вихід.

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

Бази даних SQL цікавлять детерміновані функції .

Детермінована функція завжди дає ту саму відповідь, коли вона має однакові входи. Більшість вбудованих функцій SQL у SQLite є детермінованими. Наприклад, функція abs (X) завжди повертає ту саму відповідь до тих пір, поки її вхід X однаковий.

Функція повинна бути детермінованою, якщо вона використовується для обчислення індексу.

Наприклад, в SQLite, такі недетерміновані функції не можуть бути використані в якості індексу: random(), changes(), last_insert_rowid()і sqlite3_version().


6
Запитувач func2є детермінованим (жодних випадкових наслідків не задіяно), але вже заявлено як порушує майно, яке він шукає.
Draco18s

Те, що той самий результат отримується шляхом повторення, не те саме, що сказати той же результат, який виробляється шляхом гніздування або прикування. Детерміновані функції важливі для кешування результатів, більше, ніж для індексації / хешування.
mckenzm

3

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

Особливий випадок програми, яка виробляє себе як вихід, - це квітка .


Куїни відносяться до програмного забезпечення, оскільки набори Cantor - це математика :-). І звичайно, лайки не є безсильними - вони або виходять з ладу, коли вихід вже існує, або вони "клобують" попередній результат і записують новий, хоч ідентичний вихід.
Карл Віттофт
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.