Perché Today () è un esempio di una funzione impura?

38

Sembra che, leggendo qualcosa come questo articolo di Wikipedia su "pure funzioni" , essi elencano Today() come esempio di una funzione impura ma mi sembra abbastanza pura. È perché non c'è un argomento di input formale? Perché l'ora del giorno reale non è trattata come "input alla funzione", nel qual caso se gli hai dato lo stesso input, cioè eseguito today() due volte allo stesso tempo, o viaggiato indietro nel tempo per eseguirlo di nuovo (forse un ipotetico :)), l'output sarebbe lo stesso tempo. Today() non ti dà mai un numero casuale. ti dà sempre l'ora del giorno.

L'articolo di Wikipedia dice "diverse volte produrrà risultati diversi" ma è come dire che per% differenti x % co_de ti daranno rapporti diversi. E sin(x) è il loro esempio di una funzione pura.

    
posta Brad 23.01.2013 - 16:22
fonte

10 risposte

103

Is it because there is no formal input argument?

È perché l'output dipende da qualcosa che non è un input, ovvero l'ora corrente.

Why is the actual time of day not treated as the "input to the function"

Perché non l'hai passato come parametro. Se lo hai passato come parametro, la funzione diventerebbe una funzione di identità sulle date, che è piuttosto inutile. L'intero punto di una funzione Today() è di generare qualcosa che dipende da un valore (tempo) esterno e in continua evoluzione.

Il vantaggio delle funzioni pure è che il loro comportamento è assolutamente riproducibile e deterministico, rendendo facile avere prove formali e garanzie severe. Fanno sempre la stessa cosa Today() è praticamente l'opposto: sempre (tenendo conto della granularità del tempo) fa qualcosa di diverso.

    
risposta data 23.01.2013 - 16:30
fonte
24

sin(x) restituirà sempre lo stesso valore, a condizione che x rimanga invariato. Today() potrebbe restituire risultati diversi nel tempo perché dipende da valori esterni al tuo controllo . Ad esempio, se qualcosa che sfugge al controllo del tuo programma cambia% interno% del sistema mentre il tuo programma è in esecuzione, $current_datetime produrrà improvvisamente risultati diversi.

    
risposta data 23.01.2013 - 16:23
fonte
13

Oggi () è una funzione impura perché il suo risultato dipende da qualcosa che non gli dai; in particolare, l'ora corrente del sistema. Pertanto, il suo risultato non è deterministico se basato solo sugli input forniti in fase di chiamata.

Una funzione pura sarebbe int Add(int a, int b) {return a + b;} . La funzione funziona esclusivamente con ciò che viene dato e non utilizza altri dati di stato esterni. Il risultato naturale di questo è che puoi Add(2,2) e ottenere 4 da ora fino alla fine dei tempi. Inoltre, poiché la funzione non cambia nessuno stato esterno (non ha "effetti collaterali"), Aggiungi () ing 2 e 2 da adesso fino alla fine dei tempi non cambierà nient'altro nel sistema, a meno che non si assegni il risultato della funzione a una variabile o altrimenti si usi il valore per aggiornare lo stato (che non è un'operazione eseguita dalla funzione stessa). Praticamente tutte le operazioni matematiche classiche sono funzioni pure e possono essere implementate come tali.

Oggi (), d'altra parte può produrre lo stesso valore quando viene chiamato due volte di seguito, ma non se viene chiamato ripetutamente per diversi giorni. Questo perché dipende da dati di stato esterni che non vengono forniti dall'utente come parametro della funzione. Di conseguenza, è impossibile, entro i limiti del programma, controllare il risultato della funzione Today (). Produrrà un determinato valore in un dato giorno e non produrrà mai quel valore in nessun altro giorno, a meno che non si modifichi l'orologio di sistema del computer su cui viene eseguito (un cambiamento generalmente verificatosi al di fuori dei limiti del programma). / p>

Una funzione impura non è necessariamente una cosa negativa; sono richieste funzioni impure, anche in linguaggi funzionali, per interagire con qualsiasi cosa al di fuori dei confini del programma, come archivi dati, pipeline di comunicazione, display UI, periferiche, ecc. Un programma che non fa nessuna di queste cose è un programma che è strongmente limitato nella sua utilità; Mi spingerei persino a definire un programma di questo tipo insignificante, in quanto senza alcun mezzo per accettare input o vie per informarti della sua uscita, potrebbe anche non fare nulla. I programmi scritti in linguaggi funzionali possono avere solo l'input fornito dal runtime e produrre un output segnalato al runtime senza metodi impuri esplicitamente definiti, ma questo perché il runtime sta allontanando tutti questi dettagli impuri di lavorare all'interno di un sistema informatico imperfetto, quindi che il programma stesso può essere strutturato in termini di un insieme nidificato di espressioni matematiche che il runtime valuta quindi dato un input iniziale.

È semplicemente una cosa molto buona sapere quali delle funzioni che stai usando sono pure e quali no, in modo che tu possa prendere buone decisioni su come vengono utilizzate. Funzioni impure, perché fanno cose o dipendono da cose che non sono evidenti dal loro utilizzo, possono comportarsi in modo imprevedibile dato solo la conoscenza dell'uso. È richiesta un'ulteriore conoscenza dello scopo della funzione, e quindi di cosa ha bisogno da o fa allo stato esterno, per posizionare un sistema che lo utilizza in uno stato consistente e quindi aspettarsi un risultato deterministico.

    
risposta data 23.01.2013 - 18:13
fonte
8

Sembra abbastanza ovvio che questa funzione fallisca il primo test di purezza dato all'inizio di quella pagina:

  1. The function always evaluates the same result value given the same argument value(s). The function result value cannot depend on any hidden information or state that may change as program execution proceeds or between different executions of the program, nor can it depend on any external input from I/O devices.

Si noti che poiché non richiede argomenti, esiste un solo insieme possibile di valori di argomento: il set vuoto. E questa funzione può e restituisce risultati diversi per gli stessi valori dell'argomento stesso ".

Inoltre, il valore del risultato della funzione fa dipende dallo "stato nascosto ... che può cambiare quando procede l'esecuzione del programma". Quindi un altro fallimento.

    
risposta data 23.01.2013 - 16:39
fonte
8

() => 1 sarebbe una funzione pura, poiché restituisce sempre l'1%.Today() potrebbe restituire "lunedì" o "martedì" o quasi qualsiasi altro valore.

Un altro modo di pensarci è che le funzioni pure non dipendono dallo stato. Il mondo è in genere considerato stato. Devi conoscere lo stato della realtà per sapere che giorno è oggi.

Tuttavia non è necessario sapere nulla di speciale sullo stato del mondo per sapere che cos'è sin(x) . E mai chiamare sin(x) per un dato x restituirà lo stesso valore.

    
risposta data 23.01.2013 - 16:26
fonte
2

Date(timestamp) sarebbe una pura funzione. Per la sua idempotenza. E perché non ci sarebbero effetti collaterali.

Today() può variare il suo risultato a seconda di quando lo chiami. Questo è ciò che lo rende impuro. Non è idempotente. Tuttavia non ha effetti collaterali, ma ciò non lo rende puro.

    
risposta data 23.01.2013 - 16:27
fonte
2

Ecco un piccolo pseudo-codice che penso quando si parla di pure funzioni

newValue = Function();
while(true)
{
   oldValue = newValue;
   newValue = Function();
   assert( newValue == oldValue );
}

Se viene eseguito indefinitamente e non può mai attivare l'asserzione, è una funzione pura. Inoltre, se si dispone di una funzione che utilizza arg, quindi una piccola modifica ....

oldValue = Function( importantVariableToYourApp );
newValue = Function( importantVariableToYourApp );
assert( newValue == oldValue );

Se puoi usarlo dopo ogni assegnazione di variabili nella tua app, e non cambia i risultati nella tua app, e non può mai fallire nell'asserzione, allora è una pura funzione.

    
risposta data 23.01.2013 - 21:00
fonte
2

Innanzitutto, non esiste una funzione senza argomento (o una matrice senza indici o una mappa senza chiavi). È la caratteristica di definizione di una funzione per mappare uno o più valori di argomento su un altro valore.

Quindi, today non è affatto una funzione, quindi nessuna funzione pura. Oppure possiamo interpretare la sintassi

today()

un po 'in modo che significhi

today   ()      -- today, applied to the value ()

Ad Haskell, ad esempio, questo sarebbe valido:

data Day = Mon | Tue | Wed | Thu | Fri | Sat | Sun deriving Show
today :: () -> Day
today () = ....?
main = print (today())

perché esiste un tipo () con un valore singolo ().

La domanda è solo, come può today calcolare il giorno della settimana, se solo ha ()? Non è possibile senza leggere il timer di sistema, direttamente o tramite le funzioni impure dell'help.

Il timer di sistema è un eccellente esempio per lo stato globale.

    
risposta data 24.01.2013 - 22:14
fonte
1

Il problema con today() è che può produrre un risultato diverso se chiamato due o più volte in una funzione.

Ecco un esempio di codice, che potrebbe introdurre un bug.

function doSomething(when)
{
     if(today() == when)
     {
           // open a resource or create a temp file.....
     }

     // do some other work

     if(today() == when)
     {
           // close the resource or delete temp file.....
     }
}

È possibile nell'esempio sopra. Che la seconda istruzione if non verrà eseguita. Anche se il primo ha fatto. Lasciando una risorsa in cattivo stato.

    
risposta data 24.01.2013 - 22:56
fonte
1

Per essere una funzione pura, fornire gli stessi parametri deve sempre dare lo stesso risultato.

Ogni volta che chiamiamo Today() , gli forniamo gli stessi parametri (nessuno) e tuttavia non otteniamo necessariamente lo stesso risultato (lunedì, martedì, ecc.).

    
risposta data 03.02.2015 - 12:20
fonte

Leggi altre domande sui tag