2015-07-13 9 views
6

Im Buch „Funktion Programmierung in Scala“, gibt es mehr Beispiel dafür, was „Nebenwirkungen“ ist, ist einer von ihnen:Warum "Lesen von einer Datei" ist keine reine Funktion?

  • lesen oder in eine Datei

schreiben Ich kann verstehen, "in eine Datei schreiben" ist nicht rein, weil es die Umgebung verändert. Aber warum ist das Lesen einer Datei nicht rein? Es ändert nichts.

Siehe mein Beispiel:

val readFile: File => String = file => readingTheContentFromFile(file) 
+1

Haben Sie darüber nachgedacht, wie das Lesen nur eines Teils der Datei den "Lesezeiger" der Datei ändert oder ob Sie nur die gesamte Datei lesen und davon ausgehen, dass der Inhalt der Datei immer gleich ist (was zugegebenermaßen eine Strecke)? –

+0

mögliches Duplikat von [Ist es eine reine Funktion, wenn es Daten von außerhalb statt von Parametern liest?] (Http://stackoverflow.com/questions/31376933/is-it-a-pure-function-if-it-reads -eine-Daten-von-außerhalb-lieber-als-Parameter) –

Antwort

13

Eine reine Funktion liefert durchweg den gleichen Wert der gleiche Eingang gegeben. Ansonsten basiert es auf Nebenwirkungen (wie das Ändern einer Datei). Wenn Sie von einer Datei lesen, können sich die Ergebnisse ändern, ohne dass sich die Parameter ändern.

Das relevante Konzept ist "referentielle Transparenz". Dies bedeutet, dass Sie einen Funktionsaufruf und eine bestimmte Menge von Parametern durch das Ergebnis ersetzen können, das die Funktion zurückgeben würde. Das Lesen aus einer Datei ist daher nicht referentiell transparent!

+0

Ja, eine reine Funktion kann sich nur ändern, wenn sich ihre Parameter ändern. Wenn es aus einer Datei liest, kann sich diese Datei unabhängig von den Funktionsparametern ändern. –

2

In funktionaler Programmierung, eine Funktion ist, wenn pure

  1. Die Funktion wertet immer den gleichen Ergebniswert den gleichen Argumentwert gegeben (s). Der Funktionsergebniswert kann nicht von ausgeblendeten Informationen oder einem Zustand abhängen, der sich während der Programmausführung oder zwischen verschiedenen Ausführungen des Programms ändert, noch kann er von irgendwelchen externen Eingaben von E/A-Geräten abhängig sein .
  2. Die Auswertung des Ergebnisses verursacht keine semantisch beobachtbaren Nebeneffekte oder Ausgaben, wie Mutation veränderbarer Objekte oder Ausgabe an I/O-Geräte.

I/O can be modelled in a pure way wenn

  1. die Reihenfolge der Operationen an den jeweiligen E/A-Geräten sowohl explizit als Argument modelliert wird und ein Ergebnis, und
  2. I/O-Operationen getroffen werden, zu scheitern, wenn die Eingabesequenz die seit dem Programmstart tatsächlich ausgeführten Operationen nicht beschreibt Ausführung.

Das heißt, statt tatsächlich aus einer Datei zu lesen, erhalten Sie den „Datei Inhalt“ als Parameter, und anstatt wirklich in eine Datei schreiben, Sie geben die „Datei Ausgabe“ als Wert. Dies scheint in den meisten praktischen Sprachen eine Gedankenübung zu sein.

6

Wenn eine Funktion rein ist, dann ist es immer sicher in der Ausführung common subexpression elimination heißt Sie den folgenden Pseudo-Code

do { 
    x = readFile "file.txt" 
    writeFile "file.txt" "Goodbye" 
    return (x + readFile "file.txt") 
} 

mit

do { 
    x = readFile "file.txt" 
    writeFile "file.txt" "Goodbye" 
    return (x + x) 
} 

ersetzen könnte, und Sie würden das gleiche Ergebnis.Aber wegen des Aufrufs an writeFile, der im ersten Beispiel zwischen den beiden Aufrufen an readFile erscheint, ist dies keine sichere Transformation zu machen, und daher ist die Funktion nicht rein.

+0

Danke, das ist ein gutes Beispiel! – Freewind