W informatyce mówi się, że funkcja lub wyrażenie ma efekt uboczny, jeśli zmienia jakiś stan lub ma zauważalną interakcję z funkcjami wywoływania lub światem zewnętrznym.
Z Wikipedii - Efekt uboczny
W sensie matematycznym funkcja jest odwzorowaniem między danymi wejściowymi a wyjściowymi. Zamierzonym efektem wywołania funkcji jest odwzorowanie danych wejściowych na wynik, który zwraca. Jeśli funkcja robi cokolwiek innego, nie ma znaczenia co, ale jeśli ma jakieś zachowanie, które nie mapuje danych wejściowych na dane wyjściowe, wiadomo, że takie zachowanie jest efektem ubocznym.
Mówiąc bardziej ogólnie, efektem ubocznym jest każdy efekt, który nie jest zamierzonym efektem projektanta konstrukcji.
Efektem jest wszystko, co wpływa na aktora. Jeśli wywołam funkcję, która wysyła mojej dziewczynie wiadomość tekstową zerwania, która wpływa na grupę aktorów, mnie, ją, sieć firmy komórkowej itp. Jedynym zamierzonym efektem wywołania funkcji bez skutków ubocznych jest funkcja aby zwrócić mi mapowanie z moich danych wejściowych. Więc dla:
public void SendBreakupTextMessage() {
Messaging.send("I'm breaking up with you!")
}
Jeśli ma to być funkcja, jedyne, co powinien zrobić, to return void. Jeśli byłby wolny od skutków ubocznych, nie powinien tak naprawdę wysyłać wiadomości tekstowej.
W większości języków programowania nie ma konstrukcji dla funkcji matematycznej. Żaden konstrukt nie jest przeznaczony do takiego zastosowania. Dlatego większość języków mówi, że masz metody lub procedury. Z założenia są one w stanie wykonać znacznie więcej efektów. W potocznym języku programowania nikt tak naprawdę nie dba o to, czym jest metoda lub procedura, więc kiedy ktoś mówi, że ta funkcja ma efekt uboczny, oznacza to, że konstrukcja nie zachowuje się jak funkcja matematyczna. A kiedy ktoś mówi, że ta funkcja jest wolna od efektów ubocznych, oznacza to, że konstrukcja ta zachowuje się jak funkcja matematyczna.
Z definicji czysta funkcja jest zawsze wolna od skutków ubocznych. Czysta funkcja jest sposobem, aby powiedzieć, że ta funkcja, mimo że używa konstrukcji, która pozwala na więcej efektów, ma tylko taki sam efekt jak funkcja matematyczna.
Wzywam każdego, by powiedział mi, kiedy funkcja bez skutków ubocznych nie byłaby czysta. O ile pierwotny zamierzony efekt kontekstu zdania przy użyciu terminu czysty i wolny od skutków ubocznych nie jest skutkiem matematycznego zamierzonego efektu funkcji, to są one zawsze równe.
Jako takie, czasami, choć rzadziej, i uważam, że jest to rozróżnienie, w którym brakuje ludzi, a także wprowadzających w błąd ludzi (ponieważ nie jest to najczęstsze założenie) w przyjętej odpowiedzi, ale czasami zakłada się, że zamierzonym efektem funkcji programowania jest odwzorować dane wejściowe na dane wyjściowe, gdzie dane wejściowe nie są ograniczone do jawnych parametrów funkcji, ale dane wyjściowe są ograniczone do jawnej wartości zwracanej. Jeśli założymy, że jest to zamierzony efekt, to funkcja odczytująca plik i zwracająca inny wynik na podstawie tego, co znajduje się w pliku, jest nadal wolna od efektów ubocznych, ponieważ zezwalasz na dane wejściowe pochodzące z innych miejsc zamierzonego efektu.
Dlaczego to wszystko jest tak ważne?
Chodzi o kontrolę i utrzymanie go. Jeśli wywołujesz funkcję, która robi coś innego, a następnie zwraca wartość, trudno jest uzasadnić jej zachowanie. Będziesz musiał zajrzeć do funkcji, aby znaleźć właściwy kod, aby odgadnąć, co robi i potwierdzić jego poprawność. Idealną sytuacją jest to, że jest bardzo jasne i łatwe do zrozumienia, z jakiego wejścia korzysta funkcja, i że nie robi nic innego, niż zwracanie dla niej wyniku. Możesz to trochę rozluźnić i powiedzieć, że wiedza o tym, czego używa, nie jest tak pomocna, jak pewność, że nie robi nic innego, czego możesz nie być świadomy, a następnie zwrócić wartość, więc być może jesteś zadowolony z samego tylko egzekwowania że nie robi nic innego, ale mapuje dane wejściowe, bez względu na to, skąd je bierze, na dane wyjściowe.
W prawie wszystkich przypadkach celem programu jest uzyskanie efektów innych niż mapowanie rzeczy wchodzących do rzeczy wychodzących. Idea kontrolowania efektu ubocznego polega na tym, że możesz uporządkować kod w sposób łatwiejszy do zrozumienia i uzasadnienia. Jeśli połączysz wszystkie skutki uboczne w miejscu, które jest bardzo wyraźne i centralne, łatwo jest wiedzieć, gdzie szukać i ufać, że to wszystko, co się dzieje, nigdy więcej. Jeśli dane wejściowe są również bardzo wyraźne, pomaga to przetestować zachowanie dla różnych danych wejściowych i jest łatwiejsze w użyciu, ponieważ nie trzeba zmieniać danych wejściowych w wielu różnych miejscach, niektóre z nich mogą nie być oczywiste, po prostu aby dostać to, czego chcesz.
Ponieważ najbardziej pomocne w zrozumieniu, zrozumieniu i kontrolowaniu zachowania programu jest wyraźne pogrupowanie wszystkich danych wejściowych i jednoznaczne, a także zgrupowanie wszystkich skutków ubocznych i jednoznaczne, o tym mówią ludzie, kiedy mówią efekt uboczny, czysty itp.
Ponieważ najbardziej pomocne jest grupowanie skutków ubocznych i ich jawność, czasami ludzie będą to tylko oznaczać i rozróżniać, mówiąc, że nie jest czysty, ale nadal „wolny od skutków ubocznych”. Ale efekt uboczny jest związany z założonym „zamierzonym efektem pierwotnym”, więc jest to termin kontekstowy. To, co znajduję, jest rzadziej używane, choć o dziwo w tym wątku wiele się mówi.
Wreszcie, idempotent oznacza wielokrotne wywoływanie tej funkcji z tymi samymi danymi wejściowymi (nieważne, skąd pochodzą) zawsze skutkuje tymi samymi efektami (efekt uboczny lub nie).