Cercando di riassumere le cose che sono venuti fino in altre risposte e nei commenti:
c'è solo una definizione di "idempotent". Una funzione f
è idempotente se e solo se f(f(x))
è uguale a f(x)
per tutti x
nel dominio f
.
C'è più di una definizione di "uguale". In molti contesti, abbiamo un'idea di "equivalenza" che rappresenta l'uguaglianza, e la definizione di "equivalente" potrebbe essere diversa nei diversi contesti.
C'è più di una definizione di "funzione". In matematica (con una costruzione convenzionale teorica dell'insieme), una funzione è un insieme di coppie. Il "dominio" della funzione è l'insieme di tutti gli elementi che appaiono nella prima posizione di una coppia. Nessun elemento del dominio appare nella prima posizione di più di una coppia nella funzione. La "gamma" della funzione è l'insieme di tutti gli elementi che appaiono nella seconda posizione di una coppia. Gli elementi dell'intervallo possono apparire più di una volta. Diciamo che una funzione "mappa" ogni elemento del suo dominio su un particolare elemento del suo intervallo e scriviamo f(x)
come "il secondo elemento della coppia in f
che ha come primo elemento x
".
Quindi, è chiaro che per una funzione essere idempotente, il suo intervallo deve essere un sottoinsieme del suo dominio. Altrimenti, f(f(x))
non ha senso.
In informatica, e in particolare in linguaggi imperativi, una funzione viene spesso definita come una sequenza di istruzioni/istruzioni, insieme ad alcuni input ed output con nome (nella maggior parte delle lingue c'è un solo output). "Chiamare" una funzione è un'operazione imperativa che significa eseguire le istruzioni. Ma le istruzioni in una lingua imperativa possono avere effetti collaterali: possono cambiare le cose oltre alle loro uscite. Questo concetto è assente dalla matematica, così come dalla pura programmazione funzionale.
Queste "funzioni" imperativi, che mi riferirò d'ora in poi come "routine", possono essere riconciliati con la definizione matematica di una funzione in due modi:
ignorare gli effetti collaterali, e dire che la routine è una funzione il cui dominio è l'insieme di tutte le possibili combinazioni di valori di argomento e che mappa quelli agli output della routine. Ciò si basa su un debole fondamento teorico se la funzione non è "pura", vale a dire se il suo output dipende dallo stato mutabile oltre i suoi argomenti, o se modifica lo stato oltre le sue uscite. Il motivo è che una funzione matematica per definizione non mappa i suoi input in output diversi in momenti diversi. Né una funzione matematica "cambia" le cose quando "chiama", perché le funzioni matematiche non sono "chiamate" un determinato numero di volte. Semplicemente "sono".
incorporano gli effetti collaterali in una funzione matematica che descrive l'effetto che chiamata la routine ha sullo stato completo della macchina, comprese le uscite dalla routine ma anche compresi tutti stato globale e quant'altro. Questo è un trucco standard in CS, e significa che per ogni istruzione, istruzione, chiamata a una routine o qualsiasi altra cosa, esiste una funzione corrispondente che mappa lo stato della macchina prima della chiamata, in seguito allo stato della macchina.
Ora, se applichiamo la definizione di "idempotent" nel caso in cui 1, stiamo valutando se la funzione matematica che una routine particolare è stato progettato per implementare è idempotente. Se la routine fa qualcosa di diverso dall'implementazione di una funzione matematica, ad esempio se ha effetti collaterali, allora siamo su un terreno molto traballante qui e otterremo risultati fuorvianti. Ad esempio, la funzione int f(int i) { puts("hello!"); return i; }
potrebbe essere considerata idempotente sulla base del fatto che "è un'implementazione della funzione di identità!". E questo è vero se si ignorano gli effetti collaterali, ma ciò significa che la definizione è inutile per qualsiasi scopo pratico, perché una volta che gli effetti collaterali sono presi in considerazione, l'esecuzione dell'espressione f(f(0))
è una cosa diversa dall'esecuzione dell'espressione f(0)
. f(f(0))
non è equivalente a f(0)
anche se i loro valori di ritorno sono uguali e potremmo sostituirne uno con l'altro se non ci interessa (quella parte di) l'output del programma.
Se applichiamo la definizione di "idempotente" alle funzioni degli stati macchina nel caso 2, stiamo valutando indipendentemente dal fatto che una chiamata alla funzione (con argomenti particolari) sia un'operazione di idempotenza sullo stato della macchina. Quindi la mia funzione f
sopra è chiaramente non idempotente: lo stato di una macchina con "ciao! \ N" scritto sul dispositivo di output non è lo stesso di una macchina con "ciao! \ Nhello! \ N" scritto sul suo dispositivo di output. Penso che sia anche chiaro che in questo caso, la tua funzione F
è idempotente (sebbene non sia "pura", poiché il suo valore di ritorno dipende da uno stato diverso dai suoi parametri formali, e quindi non è semplicemente un'implementazione di una funzione matematica) e la funzione F2
non è idempotente. Se test
fosse immutabile, allora potremmo ragionevolmente iniziare a descrivere F
come puro. F2
quindi non sarebbe valido.
Per quanto ne so, quando compscis parla di idempotenza in lingue imperative, di solito si parla di se le funzioni degli stati macchina definite dal caso 2, sono o non sono idempotenti. Ma l'uso può variare - se la routine è pura, allora potrebbero parlare se la funzione matematica che rappresenta è idempotente. In un puro linguaggio funzionale non c'è nessuno stato macchina di cui parlare, quindi il caso 2 sarebbe inappropriato, e qualsiasi uso del termine "idempotente" in relazione a una funzione deve essere il caso 1. Le funzioni in puro linguaggio funzionale sono sempre come funzioni matematiche .
Scusa, che cosa è ambiguo di "restituisce lo stesso risultato" o "effetti collaterali"? – Marcin
@Marcin La mia funzione F() restituisce sempre lo stesso risultato e non ha effetti collaterali, non importa quante volte lo chiami. A meno che tu non faccia qualcos'altro come chiama F2(), restituisce un risultato diverso dal risultato precedente, ma anche così, chiamandolo più volte otterrai lo stesso risultato da quel momento in poi e non ha ancora effetti collaterali. – Pacerier
Perché il downvote su questa domanda? È utile, chiaro e mostra alcuni sforzi di ricerca. – Perception