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


16

Cosa rende esattamente la lettura dalla memoria di processo un'operazione pura? Supponiamo che io abbia creato un array di 100 numeri interi nella memoria globale e poi abbia preso il 42 ° elemento di questo array. Non è un effetto collaterale, giusto? Quindi perché leggere lo stesso array di 100 numeri interi da un file è un effetto collaterale?


5
considera la modifica per spiegare cosa ti fa pensare che leggere l'array di 100 numeri interi da un file sia un effetto collaterale, così come cosa significa per te "pura operazione"
moscerino

3
@gnat Perché è I / O e I / O è un effetto collaterale
ZhekaKozlov

3
cosa ti fa pensare che l'I / O sia un effetto collaterale? prendere in considerazione la modifica per spiegare ciò per mettere in discussione i lettori. Su una nota più generale, condividere la tua ricerca aiuta tutti . Dicci cosa hai provato e perché non ha soddisfatto le tue esigenze. Ciò dimostra che hai impiegato del tempo per cercare di aiutarti, ci salva dal ribadire risposte ovvie e soprattutto ti aiuta a ottenere una risposta più specifica e pertinente. Vedi anche Come chiedere
moscerino

22
@gnat I / O è un effetto collaterale, punto. È uno degli esempi classici. Non siamo Wikipedia, non abbiamo bisogno di citazioni per la conoscenza popolare. Se pensi che qualcosa possa essere migliorato riguardo alla domanda, dillo apertamente piuttosto che passare attraverso questo uomo di paglia.

7
'O' è un effetto collaterale. 'I' è solo un effetto collaterale se fare l'io cambia lo stato di quello che stai facendo 'io'. Ciò è vero per alcune cose di I / O mappate in memoria ma è improbabile che sia il caso di un file normale.
Tom Tanner,

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 immutabile ha tipo

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

La prima versione restituisce qualcosa di tipo, il IO eche significa che ha effetti collaterali I / O. La seconda versione restituisce semplicemente un elemento di tipo esenza effetti collaterali.

In caso di accesso a un file, semplicemente non è possibile sapere in fase di compilazione se il file cambierà mai durante l'esecuzione del programma. Pertanto, devi sempre trattarlo come un'operazione con potenziali effetti collaterali.


4
Bene, con i file semplicemente non puoi essere assolutamente sicuro.
dall'8

2
Non puoi mai esserne sicuro, ma più importante: il compilatore non può esserne sicuro. Inoltre, il file system potrebbe essere danneggiato o il disco rigido potrebbe disconnettersi durante la lettura del file.
Tobias Brandt,

5
Questi non sono effetti collaterali del programma, sono effetti collaterali di altre cose. La memoria non è priva di effetti collaterali, dal momento che una particella alfa o un neutrone vagante possono capovolgere un po 'e provocare una modifica dell'array.
Blrfl,

3
@Blrfl Questo è un buon punto, tuttavia non credo che i due siano comparabili. Il danneggiamento della memoria non è qualcosa che puoi affrontare perché può influenzare i dati del programma e le istruzioni in modo arbitrario. Se succede, l'unica cosa da fare è terminare il programma (e probabilmente il sistema operativo). D'altra parte, un errore di lettura dovuto alla corruzione del file system è qualcosa che devi aspettarti ed essere in grado di gestire. È una parte inerente alla gestione dei file.
Tobias Brandt,

2
Stai uscendo dal regno degli effetti collaterali e nel rilevamento e nella gestione degli errori, che è una discussione completamente diversa. La questione degli effetti collaterali è una questione se un'operazione abbia o meno effetti su qualcos'altro, se il risultato dell'operazione può o meno essere influenzato o meno da fattori esterni.
Blrfl,

10

Nell'informatica, si dice che una funzione o espressione abbia un effetto collaterale se, oltre a restituire un valore, modifica anche qualche stato 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. Soddisfa la definizione di effetto collaterale. Leggere il 42 ° elemento dalla memoria globale sarebbe anche 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.


2

Se si dispone di un handle di file condiviso, la lettura di un file sposta tale handle di file nella posizione in cui è stato letto e lo lascia in tale posizione.

Se hai due thread con handle di file separati nello stesso file, la lettura da uno non avrà alcun effetto collaterale evidente sull'altro.

Tuttavia, in entrambi questi casi, la lettura della memoria e la lettura dei file potrebbero causare effetti collaterali nascosti nella memorizzazione nella cache del sistema dell'operatore.


0

La lettura dalla memoria non influenza altre funzioni ed è quindi priva di effetti collaterali. La lettura da un file in genere sposta il puntatore di posizione del file, in modo che quando rileggi di nuovo leggi i dati dopo quello che hai già letto, quindi una funzione di lettura cambia il risultato di altre funzioni di lettura, il che è un effetto collaterale. Se invece apri, leggi e chiudi un file in una volta, questo effetto collaterale scompare, ma ciò non è fattibile per 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 successivi tentativi falliranno con un errore File già aperto , che di nuovo è un effetto collaterale.

La creazione di una funzione di lettura senza effetti collaterali che legge il file in una volta sola e consente più letture contemporaneamente è difficile perché ci sono funzioni di scrittura di file che vengono influenzate dalla funzione di lettura e liberarsi delle funzioni di scrittura di file non è di nuovo possibile .


1
Potresti avere la lettura libera di effetti collaterali da un file se il file non è cambiato e hai trasformato il file in un flusso (elenco pigro).
Giorgio,

2
Raggiungere il sistema operativo per un file che non è sotto il tuo controllo è un effetto collaterale. Solo se potessi controllare la mutabilità del file (e forse le operazioni di muting in sequenza su di esso ... tramite la IOmonade?) Potresti creare una funzione priva di effetti collaterali per la lettura.
Bergi,

0

La lettura da un flusso è già un effetto collaterale perché il risultato di funzioni come isEOFpotrebbe restituire un risultato diverso dopo la lettura rispetto a prima della lettura.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.