Perché la lettura dalla memoria non è un effetto collaterale, ma la lettura da un file è?

15

Che cosa fa esattamente la lettura della memoria di processo un'operazione pura? Supponiamo di aver creato un array di 100 numeri interi nella memoria globale e di aver preso il 42 ° elemento di questo array. Non è un effetto collaterale, giusto? Allora perché sta leggendo lo stesso array di 100 interi da un file un effetto collaterale?

    
posta ZhekaKozlov 08.10.2014 - 12:15
fonte

5 risposte

27

Se la memoria a cui accedi può cambiare, allora è davvero un effetto collaterale.

Ad esempio, in Haskell, la funzione per accedere a un array mutabile ( IOArray ) ha tipo

Ix i => IOArray i e -> i -> IO e

(leggermente semplificato per i nostri scopi). Durante l'accesso a un array immutable ha tipo

Ix i => Array i e -> i -> e

La prima versione restituisce qualcosa di tipo IO e che significa che ha effetti collaterali I / O. La seconda versione restituisce semplicemente un elemento di tipo e senza effetti collaterali.

In caso di accesso a un file, semplicemente non puoi sapere al momento della compilazione se il file cambierà durante l'esecuzione del programma. Pertanto, devi sempre trattarlo come un'operazione con potenziali effetti collaterali.

    
risposta data 08.10.2014 - 12:29
fonte
10

In informatica, una funzione o un'espressione ha un effetto collaterale se, oltre a restituire un valore, modifica anche alcuni stati o ha un'interazione osservabile con le funzioni di chiamata o il mondo esterno. Leggere da un file è un'interazione osservabile con il mondo esterno. Risponde alla definizione di effetto collaterale. Leggere il 42esimo elemento dalla memoria globale sarebbe un effetto collaterale, a meno che l'array non sia una costante perché sarebbe un'interazione osservabile con altre funzioni che potrebbero modificare l'array.

    
risposta data 08.10.2014 - 16:56
fonte
2

Se hai un handle di file condiviso, la lettura di un file sposterà l'handle del file nella posizione in cui hai letto e lo lascerà in quella posizione.

Se hai due thread con handle di file separati sullo stesso file, la lettura da uno non avrà effetti collaterali evidenti sull'altro.

Tuttavia in entrambi questi casi, lettura della memoria e lettura dei file, potrebbe esserci un effetto collaterale nascosto della memorizzazione nella cache del sistema operativo.

    
risposta data 08.10.2014 - 12:57
fonte
0

La lettura dalla memoria non influenza altre funzioni ed è quindi privo di effetti collaterali. La lettura da un file in genere sposta il puntatore di posizione del file, in modo che quando leggi di nuovo leggi i dati dopo ciò che hai già letto, così una funzione di lettura cambia il risultato di altre funzioni di lettura, che è un effetto collaterale. Se invece apri, leggi e chiudi un file in un colpo solo, questo effetto collaterale scompare, ma ciò non è fattibile per i file di grandi dimensioni. Inoltre, a seconda di come si apre il file, potrebbe bloccarsi dopo averlo aperto, quindi il primo tentativo di aprire e leggere il file ha esito positivo mentre i tentativi successivi falliscono con un errore File già aperto , che di nuovo è un effetto collaterale.

Creazione di una funzione di lettura senza effetti collaterali che legge il file in una volta sola e consente più letture allo stesso tempo è difficile perché ci sono funzioni di scrittura del file che vengono influenzate dalla funzione di lettura e liberarsi delle funzioni di scrittura dei file è di nuovo non fattibile.

    
risposta data 08.10.2014 - 12:50
fonte
0

La lettura da un flusso è già un effetto collaterale perché il risultato di funzioni come isEOF può restituire risultati diversi dopo la lettura rispetto a prima della lettura.

    
risposta data 08.10.2014 - 16:45
fonte

Leggi altre domande sui tag