Warum ist das Lesen aus dem Speicher kein Nebeneffekt, aber das Lesen aus einer Datei?


16

Was genau macht das Lesen aus dem Prozessspeicher zu einem reinen Vorgang? Angenommen, ich habe ein Array mit 100 Ganzzahlen im globalen Speicher erstellt und dann das 42. Element dieses Arrays verwendet. Es ist keine Nebenwirkung, oder? Warum ist das Lesen des gleichen Arrays von 100 Ganzzahlen aus einer Datei ein Nebeneffekt?


5
Sehen Sie bearbeitet ing zu erklären , was das Sie denken , macht aus einer Datei das Array von 100 ganzen Zahlen Lesen ein Nebeneffekt ist, als auch, was bedeutet „reinen Betrieb“ für dich
gnat

3
@ Gnat Weil es I / O und I / O ist ein Nebeneffekt
ZhekaKozlov

3
Was lässt Sie denken, dass E / A ein Nebeneffekt ist? erwägen Sie , dies zu erklären, um die Leser zu befragen. Allgemeiner gesagt, hilft das Teilen Ihrer Forschung jedem . Sagen Sie uns, was Sie versucht haben und warum es nicht Ihren Bedürfnissen entsprach. Dies zeigt, dass Sie sich die Zeit genommen haben, um sich selbst zu helfen, es erspart uns, offensichtliche Antworten zu wiederholen, und vor allem hilft es Ihnen, eine spezifischere und relevantere Antwort zu erhalten. Siehe auch Wie man fragt
Mücke

22
@gnat I / O ist ein Nebeneffekt, Punkt. Es ist eines der klassischen Beispiele. Wir sind keine Wikipedia, wir brauchen keine Zitate für Volkskenntnisse. Wenn Sie der Meinung sind, dass die Frage verbessert werden kann, sagen Sie es direkt, anstatt durch diesen Strohmann zu gehen.

7
'O' ist eine Nebenwirkung. "Ich" ist nur ein Nebeneffekt, wenn das "Ich" den Zustand von dem ändert, von dem aus Sie "Ich" tun. Dies gilt für bestimmte speicherabgebildete E / A-Vorgänge, ist jedoch bei einer normalen Datei wahrscheinlich nicht der Fall.
Tom Tanner

Antworten:


27

Wenn sich der Speicher, auf den Sie zugreifen, ändern kann, handelt es sich in der Tat um einen Nebeneffekt.

In Haskell hat die Funktion zum Zugreifen auf ein veränderliches Array ( IOArray) beispielsweise den Typ

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

(für unsere Zwecke leicht vereinfacht). Während des Zugriffs auf ein unveränderliches Array hat Typ

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

Die erste Version gibt etwas vom Typ zurück, IO ewas bedeutet, dass sie I / O-Nebenwirkungen hat. Die zweite Version gibt einfach ein Element vom Typ eohne Nebenwirkungen zurück.

Wenn Sie auf eine Datei zugreifen, können Sie beim Kompilieren einfach nicht wissen, ob sich die Datei während eines Programmlaufs jemals ändern wird. Daher müssen Sie es immer als eine Operation mit möglichen Nebenwirkungen behandeln.


4
Nun, bei Dateien kann man einfach nicht absolut sicher sein.
08.10.2014

2
Sie können nie sicher sein, aber wichtiger: Der Compiler kann nicht sicher sein. Darüber hinaus wird Ihr Dateisystem möglicherweise beschädigt oder die Verbindung zur Festplatte wird unterbrochen, während Sie die Datei lesen.
Tobias Brandt

5
Das sind keine Nebenwirkungen des Programms, sondern Nebenwirkungen anderer Dinge. Der Speicher ist auch nicht nebenwirkungsfrei, da ein Alphateilchen oder ein Streuneutron ein wenig kippen und zu einer Änderung des Arrays führen kann.
Blrfl

3
@Blrfl Das ist ein guter Punkt, aber ich denke nicht, dass die beiden vergleichbar sind. Mit Speicherbeschädigung können Sie nicht umgehen, da sie die Programmdaten und -anweisungen auf beliebige Weise beeinflussen kann. In diesem Fall müssen Sie nur das Programm (und wahrscheinlich auch das Betriebssystem) beenden. Andererseits ist ein Lesefehler aufgrund einer Beschädigung des Dateisystems etwas, das Sie erwarten müssen und das Sie handhaben können. Es ist ein fester Bestandteil des Umgangs mit Dateien.
Tobias Brandt

2
Sie verlassen den Bereich der Nebenwirkungen und befassen sich mit der Fehlererkennung und -behandlung, was eine völlig andere Diskussion ist. Bei den Nebenwirkungen handelt es sich um die Frage, ob eine Operation Auswirkungen auf etwas anderes hat oder nicht und ob das Ergebnis der Operation durch externe Faktoren beeinflusst werden kann oder nicht.
Blrfl

10

In der Informatik hat eine Funktion oder ein Ausdruck eine Nebenwirkung, wenn sie nicht nur einen Wert zurückgibt, sondern auch einen bestimmten Zustand ändert oder eine beobachtbare Wechselwirkung mit aufrufenden Funktionen oder der Außenwelt aufweist. Das Lesen aus einer Datei ist eine beobachtbare Interaktion mit der Außenwelt. Es erfüllt die Definition der Nebenwirkung. Das Lesen des 42. Elements aus dem globalen Speicher ist ebenfalls ein Nebeneffekt, es sei denn, Ihr Array ist eine Konstante, da dies eine beobachtbare Interaktion mit anderen Funktionen ist, die das Array möglicherweise ändern.


2

Wenn Sie über ein freigegebenes Dateihandle verfügen, wird beim Lesen einer Datei dieses Dateihandle an die Position verschoben, an der Sie es gelesen haben, und an dieser Position belassen.

Wenn Sie zwei Threads mit separaten Dateizugriffspunkten für dieselbe Datei haben, hat das Lesen von einem Thread keine nennenswerten Nebenwirkungen auf den anderen.

In beiden Fällen, beim Lesen des Speichers und beim Lesen von Dateien, kann es jedoch zu versteckten Nebeneffekten beim Zwischenspeichern des Betriebssystems kommen.


0

Das Auslesen aus dem Speicher hat keinen Einfluss auf andere Funktionen und ist daher nebenwirkungsfrei. Beim Lesen aus einer Datei wird in der Regel der Positionszeiger der Datei verschoben. Wenn Sie also erneut lesen, lesen Sie die Daten nach dem, was Sie bereits gelesen haben. Dadurch ändert eine Lesefunktion das Ergebnis anderer Lesefunktionen. Dies ist ein Nebeneffekt. Wenn Sie stattdessen eine Datei auf einmal öffnen, lesen und schließen, verschwindet dieser Nebeneffekt. Dies ist jedoch für große Dateien nicht möglich. Abhängig davon, wie Sie die Datei öffnen, kann sie nach dem Öffnen gesperrt werden. Der erste Versuch, die Datei zu öffnen und zu lesen, schlägt fehl, während die folgenden Versuche mit dem Fehler " Datei bereits geöffnet" fehl , was wiederum ein Nebeneffekt ist.

Das Erstellen einer nebenwirkungsfreien Lesefunktion, die die Datei auf einmal liest und mehrere Lesevorgänge gleichzeitig zulässt, ist schwierig, da es Dateischreibfunktionen gibt, die von der Lesefunktion beeinflusst werden, und das Entfernen der Dateischreibfunktionen ist wiederum nicht möglich .


1
Wenn sich die Datei nicht geändert hat und Sie die Datei in einen Stream verwandelt haben (Lazy List), können Sie eine Datei ohne Nebenwirkungen lesen.
Giorgio

2
Es ist ein Nebeneffekt , sich an das Betriebssystem zu wenden, um eine Datei zu erhalten, die nicht unter Ihrer Kontrolle steht . Nur wenn Sie die Veränderbarkeit der Datei kontrollieren könnten (und möglicherweise Sequenzveränderungsoperationen darauf ... über die IOMonade?), Könnten Sie eine nebenwirkungsfreie Funktion zum Lesen erstellen .
Bergi

0

Das Lesen aus einem Stream ist bereits ein Nebeneffekt, da das Ergebnis von Funktionen wie beispielsweise isEOFnach dem Lesen ein anderes Ergebnis zurückgeben kann als vor dem Lesen.

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.