Ich habe das Konzept der Nebenwirkung nicht klar verstanden.
- Was ist ein Nebeneffekt bei der Programmierung?
- Ist es programmiersprachenabhängig?
- Gibt es äußere und innere Nebenwirkungen?
Bitte geben Sie ein Beispiel für Ursachen, die Nebenwirkungen hervorrufen.
programming-languages
functional-programming
Amir Rezaei
quelle
quelle
Antworten:
Ein Nebeneffekt bezieht sich einfach auf die Änderung eines Zustands - zum Beispiel:
Im Gegensatz zu dem, was manche Leute zu sagen scheinen:
Ein Nebeneffekt muss nicht verborgen oder unerwartet sein (es kann sein, aber das hat nichts mit der Definition zu tun, wie sie für die Informatik gilt);
Ein Nebeneffekt hat nichts mit Idempotenz zu tun. Eine idempotente Funktion kann Nebenwirkungen haben, und eine nicht idempotente Funktion kann keine Nebenwirkungen haben (z. B. das Abrufen des aktuellen Systemdatums und der aktuellen Systemzeit).
Es ist wirklich sehr einfach. Nebeneffekt = irgendwo etwas ändern.
PS Wie Kommentator Benjamin betont, können mehrere Personen die Definition einer Nebenwirkung mit der Definition einer reinen Funktion in Konflikt bringen. Diese Funktion ist (a) idempotent und (b) hat keine Nebenwirkungen. Das eine impliziert das andere in der allgemeinen Informatik nicht, aber funktionale Programmiersprachen tendieren typischerweise dazu, beide Einschränkungen durchzusetzen.
quelle
++a
. Sieht nicht nach Aufgabe aus.b = ++a;
hat zwei Nebenwirkungen. Das Offensichtliche und die Krypto-Zuordnung vona
. So etwas ist ein Nebeneffekt, der (für manche) wünschenswert ist. Wurde aber als Nebeneffekt für meine gesamte Karriere bezeichnet, um es nicht subtil zu machen.Jede Operation, die den Zustand des Computers verändert oder mit der Außenwelt interagiert, soll einen Nebeneffekt haben. Siehe Wikipedia zu Nebenwirkungen .
Diese Funktion hat beispielsweise keine Nebenwirkungen. Das Ergebnis hängt nur von den Eingabeargumenten ab und es ändert sich nichts am Status des Programms oder seiner Umgebung, wenn es aufgerufen wird:
Im Gegensatz dazu erhalten Sie beim Aufrufen dieser Funktionen je nach der Reihenfolge, in der Sie sie aufrufen, unterschiedliche Ergebnisse, da sie etwas am Status des Computers ändern:
Diese Funktion hat den Nebeneffekt, dass Daten in die Ausgabe geschrieben werden. Sie rufen die Funktion nicht auf, weil Sie ihren Rückgabewert wollen. Sie nennen es, weil Sie die Wirkung haben möchten, die es auf die "Außenwelt" hat:
quelle
Write
Beispiel zeigt, bedeutet das Vorhandensein von Nebenwirkungen nicht, dass die Funktion ihre Ausgabe in Bezug auf ihre Eingaben ändert oder dass ihre Ausgabe überhaupt von der Eingabe abhängt.square(x)
dazu führen, dass das Modul, in dem die Funktion definiert ist, von der Festplatte geladen wird. Sollte dies als Nebenwirkung angesehen werden? Immerhin ist dies Männer, dass der (erste) Aufruf unerwartet lange dauert, die RAM-Auslastung steigt usw.square(x)
weil Sie möchten, dass sich der Status des externen Computers ändert, können Sie dies als Nebeneffekt betrachten.Ich denke, dass die vorhandenen Antworten ziemlich gut sind. Ich möchte auf einige Aspekte eingehen, auf die die IMO nicht genug Wert gelegt hat.
In der Mathematik ist eine Funktion nur eine Abbildung von einem Tupel von Werten auf einen Wert. Wenn Sie also eine Funktion
f
und einen Wert angebenx
, erhalten Sief(x)
immer das gleiche Ergebnisy
. Sie können auch ersetzenf(x)
mity
überall in einem Ausdruck und wird sich nichts ändern.Was in vielen Programmiersprachen als Funktion (oder Prozedur) bezeichnet wird, ist ein Konstrukt (Stück Code), das ausgeführt werden kann, weil:
Effekte können sich also auf den Zustand beziehen, aber auch auf andere Aspekte wie das Abfeuern einer Rakete oder das Unterbrechen der Ausführung für einige Sekunden.
Der Begriff Nebenwirkung mag negativ klingen, aber normalerweise ist die Wirkung des Aufrufs einer Funktion der eigentliche Zweck der Funktion. Ich nehme an, da der Begriff Funktion ursprünglich in der Mathematik verwendet wurde, wird das Berechnen eines Werts als der primäre Effekt einer Funktion angesehen, während alle anderen Effekte als Nebenwirkungen betrachtet werden . Einige Programmiersprachen verwenden den Begriff Prozedur , um Verwechslungen mit Funktionen im mathematischen Sinne zu vermeiden.
Beachten Sie, dass
sleep()
in Python, sind nur für ihre (Nebenwirkungen) nützlich. Diese werden häufig als Funktionen modelliert, die einen speziellen Wert zurückgebenNone
, oderunit
oder()
oder ..., der lediglich angibt, dass die Berechnung korrekt beendet wurde.quelle
Ein Nebeneffekt ist, wenn eine Operation eine Auswirkung auf eine Variable / ein Objekt hat, die / das außerhalb der beabsichtigten Verwendung liegt.
Dies kann passieren, wenn Sie eine komplexe Funktion aufrufen, die nebenbei eine globale Variable ändert, obwohl Sie sie nicht aus diesem Grund aufgerufen haben (vielleicht haben Sie sie aufgerufen, um etwas aus einer Datenbank zu extrahieren).
Ich gebe zu, dass ich Probleme habe, ein einfaches Beispiel zu finden, das nicht völlig durchdacht aussieht, und Beispiele von Dingen, an denen ich gearbeitet habe, sind viel zu lang, um sie hier zu posten (und da es arbeitsbezogen ist, sollte ich es wahrscheinlich auch nicht tun ).
Ein Beispiel, das ich (vor einiger Zeit) gesehen habe, war eine Funktion, die eine Datenbankverbindung öffnete, wenn die Verbindung geschlossen war. Das Problem bestand darin, dass die Verbindung am Ende der Funktion getrennt werden sollte, der Entwickler jedoch vergaß, diesen Code hinzuzufügen. Hier gab es also einen unbeabsichtigten Nebeneffekt: Der Aufruf einer Prozedur sollte nur eine Abfrage ausführen, und der Nebeneffekt war, dass die Verbindung offen blieb. Wenn die Funktion zweimal hintereinander aufgerufen wurde, wurde ein Fehler ausgegeben, der besagte, dass die Verbindung aktiv war bereits geöffnet.
Ok, da jetzt alle Beispiele geben, denke ich, werde ich auch;)
Die Funktion
do_task_x
hat eine primäre Wirkung das Ergebnis einiger Berechnungen zurückkehrt, und einen Nebeneffekt von möglicherweise eine globale Variable zu verändern.Natürlich, welches ist das primäre und das ist die Nebenwirkung Interpretation offen sein könnte und der tatsächlichen Nutzung abhängen könnte. Wenn ich diese Funktion aufrufen zu dem Zweck , die globale modifizieren und ich verwerfen den Wert zurück , als ich würde sagen , dass die globale Modifikation der Primäreffekt ist.
quelle
Aus Wikipedia - Nebeneffekt
Eine Funktion im mathematischen Sinne ist eine Abbildung von Eingabe zu Ausgabe. Durch den Aufruf einer Funktion soll die Eingabe der von ihr zurückgegebenen Ausgabe zugeordnet werden. Wenn die Funktion etwas anderes ausführt, spielt es keine Rolle, aber wenn sie ein Verhalten aufweist, bei dem die Eingabe nicht der Ausgabe zugeordnet wird, ist dieses Verhalten als Nebeneffekt bekannt.
Allgemeiner ausgedrückt ist eine Nebenwirkung jede Wirkung, die nicht die beabsichtigte Wirkung des Konstrukteurs ist.
Ein Effekt ist alles, was einen Schauspieler betrifft. Wenn ich eine Funktion aufrufe, die meiner Freundin eine Trennungstextnachricht sendet, die eine Reihe von Akteuren betrifft, mich, sie, das Netzwerk der Mobiltelefonfirma usw. Der einzige beabsichtigte Effekt beim Aufrufen einer nebenwirkungsfreien Funktion ist die Funktion um mir eine Zuordnung von meiner Eingabe zurückzugeben. So für:
Wenn dies eine Funktion sein soll, ist das einzige, was es tun sollte, die Rückgabe für ungültig zu erklären. Wenn es nebenwirkungsfrei ist, sollte es die Textnachricht nicht wirklich senden.
In den meisten Programmiersprachen gibt es kein Konstrukt für eine mathematische Funktion. Kein Konstrukt soll als solches verwendet werden. Aus diesem Grund geben die meisten Sprachen an, dass Sie über Methoden oder Verfahren verfügen. Mit diesen sollen wesentlich mehr Effekte erzielt werden können. In der gewöhnlichen Programmiersprache kümmert sich niemand wirklich um die Absicht einer Methode oder Prozedur. Wenn also jemand sagt, dass diese Funktion Nebenwirkungen hat, bedeutet dies, dass sich dieses Konstrukt nicht wie eine mathematische Funktion verhält. Und wenn jemand sagt, dass diese Funktion frei von Nebenwirkungen ist, bedeutet dies, dass sich dieses Konstrukt effektiv wie eine mathematische Funktion verhält.
Eine reine Funktion ist per Definition immer nebenwirkungsfrei. Eine reine Funktion ist eine Art zu sagen, dass diese Funktion, obwohl sie ein Konstrukt verwendet, das mehr Effekte zulässt, nur die gleiche Wirkung hat wie eine mathematische Funktion.
Ich fordere jeden auf, mir zu sagen, wann eine nebenwirkungsfreie Funktion nicht rein wäre. Sofern der primäre beabsichtigte Effekt des Kontextes des Satzes unter Verwendung des Begriffs rein und nebenwirkungsfrei nicht der des mathematisch beabsichtigten Effekts einer Funktion ist, sind diese immer gleich.
Als solche, manchmal, wenn auch seltener, und ich glaube, dies ist die Unterscheidung, die Menschen fehlen und auch irreführen (da dies nicht die häufigste Annahme ist), in der akzeptierten Antwort, aber manchmal wird angenommen, dass die beabsichtigte Wirkung einer Programmierfunktion ist um die Eingabe der Ausgabe zuzuordnen, wobei die Eingabe nicht auf die expliziten Parameter der Funktion beschränkt ist, sondern die Ausgabe auf den expliziten Rückgabewert beschränkt ist. Wenn Sie davon ausgehen, dass dies der beabsichtigte Effekt ist, ist eine Funktion, die eine Datei liest und basierend auf dem Inhalt der Datei ein anderes Ergebnis zurückgibt, immer noch nebenwirkungsfrei, da Sie Eingaben von anderen Stellen in Ihrem beabsichtigten Effekt zugelassen haben.
Warum ist das alles so wichtig?
Es geht darum, alles zu kontrollieren und zu behalten. Wenn Sie eine Funktion aufrufen und sie etwas anderes ausführt, als einen Wert zurückzugeben, ist es schwierig, ein Urteil über ihr Verhalten zu fällen. Sie müssen in der Funktion nach dem tatsächlichen Code suchen, um zu erraten, was er tut, und um seine Richtigkeit zu bestätigen. Die ideale Situation ist, dass es sehr klar und einfach ist, zu wissen, welche Eingabe die Funktion verwendet, und dass sie nichts anderes tut, als eine Ausgabe dafür zurückzugeben. Sie können sich ein wenig entspannen und sagen, dass es nicht so hilfreich ist, genau zu wissen, welche Eingabe verwendet wird, als sicher zu sein, dass sie nichts anderes tut, von dem Sie vielleicht nichts wissen, als einen Wert zurückzugeben. Vielleicht geben Sie sich also nur mit der Durchsetzung zufrieden dass es nichts anderes tut, als Eingaben abzubilden, egal woher es kommt, um sie auszugeben.
In fast allen Fällen besteht der Sinn eines Programms darin, andere Effekte zu erzielen, als Dinge, die hereinkommen, auf Dinge, die herauskommen, abzubilden. Die Idee, den Nebeneffekt zu kontrollieren, besteht darin, dass Sie Code auf eine Weise organisieren können, die verständlicher und verständlicher ist. Wenn Sie alle Nebenwirkungen an einem Ort zusammenfassen, der sehr explizit und zentral ist, ist es leicht zu wissen, wo Sie suchen und darauf vertrauen können, dass dies alles ist, was passiert, und nicht mehr. Wenn die Eingabe auch sehr eindeutig ist, können Sie das Verhalten für verschiedene Eingaben testen und es ist einfacher zu verwenden, da Sie die Eingabe nicht an vielen verschiedenen Stellen ändern müssen, von denen einige möglicherweise nicht offensichtlich sind um zu bekommen was du willst.
Da das Verständnis, die Vernunft und die Kontrolle des Verhaltens eines Programms am hilfreichsten ist, wenn alle Eingaben klar und eindeutig gruppiert sind und alle Nebenwirkungen klar und eindeutig zusammengefasst sind, wird in der Regel darüber gesprochen Nebenwirkung, pur usw.
Da die Gruppierung der Nebenwirkungen und ihre Aussagekraft am hilfreichsten sind, wird dies manchmal nur gemeint sein und dadurch unterschieden, dass es nicht rein ist, aber dennoch frei von "Nebenwirkungen". Die Nebenwirkung ist jedoch relativ zur angenommenen "beabsichtigten primären Wirkung", es handelt sich also um einen Kontextbegriff. Dies wird, wie ich finde, seltener verwendet, obwohl in diesem Thread überraschenderweise viel darüber gesprochen wird.
Schließlich bedeutet idempotent, dass das mehrmalige Aufrufen dieser Funktion mit denselben Eingaben (egal woher sie kommen) immer dieselben Effekte zur Folge hat (Nebeneffekt oder nicht).
quelle
Bei der Programmierung ist ein Nebeneffekt, wenn eine Prozedur eine Variable von außerhalb ihres Gültigkeitsbereichs ändert. Nebenwirkungen sind nicht sprachabhängig. Es gibt einige Klassen von Sprachen, die darauf abzielen, Nebenwirkungen zu beseitigen (reine Funktionssprachen), aber ich bin mir nicht sicher, ob es Nebenwirkungen gibt, aber ich könnte mich irren.
Soweit ich weiß, gibt es keine internen und externen Nebenwirkungen.
quelle
Hier ist ein einfaches Beispiel:
Die Definition von Nebenwirkungen ist nicht programmspezifisch. Stellen Sie sich einfach die Nebenwirkungen Ihrer Medikamente vor oder essen Sie zu viel.
quelle
x++
die Variable ändert,x
wird häufig als Nebeneffekt angesehen. Dieser Wert des Ausdrucks ist der Vorinkrementierungswert vonx
; Dies ist der nebenwirkungsfreie Teil des Ausdrucks.Ein Nebeneffekt sind Dinge, die in Code vorkommen, die nicht offensichtlich sind.
Nehmen wir zum Beispiel an, Sie haben diese Klasse
Wenn Sie die Klasse zum ersten Mal erstellen, geben Sie ihr einen Startwert.
Sie kennen die Interna nicht, Sie erwarten nur einen zufälligen Wert und Sie würden erwarten, dass der randomGenerator.Seed immer noch 15 ist ... aber es ist nicht.
Der Funktionsaufruf hatte den Nebeneffekt, dass der Seed-Wert geändert wurde.
quelle