Una funzione può essere pura se dipende da un campo di istanza immutabile?

5

Nell'esempio di codice c # seguente, il campo di istanza [nome] è di sola lettura e pertanto è immutabile dopo la costruzione della classe.

public sealed class Example
{
    public readonly string name;

    public Example(string name)
    {
        this.name = name;
    }

    public string AllUppercase()
    {
        return this.name.ToUpper();
    }
}

Il metodo [AllUpperCase] è idempotente e ha zero effetti collaterali. Tuttavia, il metodo dipende dallo stato immutabile che è esterno al metodo. Questo metodo si qualifica come puro?

    
posta Rock Anthony Johnson 21.10.2016 - 03:04
fonte

3 risposte

12

Sì, quella funzione è effettivamente pura.

Non ha effetti collaterali. È idempotente. Dipende solo dagli input (incluso this ) e quegli input sono anche pure.

O per pensarci in un altro modo, supponiamo che AllUppercase sia una funzione statica che ha preso un Example e ne ha usato il name - che ovviamente sarebbe una pura funzione. Le funzioni dei membri non sono diverse.

    
risposta data 21.10.2016 - 03:18
fonte
6

Quando si tenta di pensare alla notazione di punti da OO in termini di FP, di solito ha senso considerare la roba prima del punto come primo argomento di una funzione. (Quindi, pensa a x.f() come f(x) e x.f(y) a f(x,y) )

Fondamentalmente, questa domanda si riduce alla seguente: Ho una funzione pura f e un valore immutabile x ; è f(x) una funzione pura?

( f è ToUpper e x è this.name )

Sembra meglio chiamare f(x) un valore. Poiché si tratta di una funzione pura applicata a un valore immutabile, è un valore immutabile.

    
risposta data 21.10.2016 - 12:15
fonte
3

Ecco i miei due centesimi. Una funzione in senso matematico è una mappatura dai valori di input a un valore di output e nient'altro. Non stampa "Hello world!", E così via. Non calcola nemmeno nulla.

Molti linguaggi di programmazione usano il termine funzione per indicare un pezzo di codice autonomo che può assumere parametri e può restituire un valore. Un altro termine è la procedura. I linguaggi orientati agli oggetti hanno metodi, che sono procedure integrate con oggetti: vengono invocati con l'oggetto stesso come argomento implicito e hanno accesso alle variabili membro interne dell'oggetto.

Quando viene invocato, una procedura può eseguire un numero di operazioni come leggere / scrivere su variabili (posizioni di memoria) o dispositivi IO (file, tastiera e così via).

Il termine pure è stato introdotto per indicare le funzioni del linguaggio di programmazione (procedure) il cui effetto only è calcolare una funzione in senso matematico: dati alcuni valori di input, calcola un risultato e restituiscilo.

Guardando l'esempio dell'OP. Come hanno sottolineato altre risposte, poiché AllUppercase() è invocato con l'oggetto stesso come input implicito, puoi considerarlo una mappatura dagli oggetti alle stringhe. Quindi

  1. Per ogni oggetto dato, AllUppercase() restituirà sempre la stessa stringa e
  2. invocare AllUppercase() non ha alcun effetto osservabile diverso da quello descritto al punto 1.

Quindi AllUppercase() calcola una funzione solo in senso matematico, cioè è una pura funzione nel senso del linguaggio di programmazione.

Per quanto riguarda l'idea di un ingresso mutevole, puro input. Penso che sia importante definire con precisione cosa sia un input e cosa significhi stesso input . Supponiamo che il membro name nella classe Example sia mutabile. Quindi ora invochi AllUppercase() e ottieni un risultato. Quindi si modifica name , si richiama di nuovo il metodo e si ottiene un risultato diverso.

  • Se definisci lo stesso input come "same memory location" (stesso riferimento all'oggetto), la funzione ha prodotto due risultati diversi con lo stesso input == > non puro.

  • Se definisci lo stesso input tramite l'uguaglianza dell'oggetto (il risultato del metodo "Equals" in C #), allora AllUppercase() è ancora puro: quando lo invochi su un oggetto mutato, stai passando un input diverso quindi non è un problema che restituisca un risultato diverso.

Bottomline: per ragionare sulla purezza quando si usano i dati mutabili devi essere preciso su ciò che consideri i tuoi input: indirizzi / variabili o valori contenuti nelle variabili? Questa distinzione è irrilevante quando si tratta di dati immutabili.

    
risposta data 22.10.2016 - 09:58
fonte

Leggi altre domande sui tag