Co dokładnie czyni odczyt z pamięci procesu czystą operacją? Załóżmy, że utworzyłem tablicę 100 liczb całkowitych w pamięci globalnej, a następnie wziąłem 42 element tej tablicy. To nie jest efekt uboczny, prawda? Dlaczego więc odczytanie tej samej tablicy 100 liczb całkowitych z pliku jest efektem ubocznym?
functional-programming
side-effect
ZhekaKozlov
źródło
źródło
Odpowiedzi:
Jeśli pamięć, do której masz dostęp, może się zmienić, to rzeczywiście jest to efekt uboczny.
Na przykład w Haskell funkcja dostępu do tablicy zmiennych (
IOArray
) ma typ(nieco uproszczone dla naszych celów). Podczas uzyskiwania dostępu do niezmiennej tablicy ma typ
Pierwsza wersja zwraca coś w rodzaju,
IO e
co oznacza, że ma skutki uboczne I / O. Druga wersja po prostu zwraca element typue
bez żadnych skutków ubocznych.W przypadku uzyskania dostępu do pliku, po prostu nie możesz wiedzieć w czasie kompilacji, czy plik kiedykolwiek się zmieni podczas uruchamiania programu. Dlatego zawsze należy traktować to jako operację z potencjalnymi skutkami ubocznymi.
źródło
W informatyce mówi się, że funkcja lub wyrażenie ma efekt uboczny, jeśli oprócz zwracania wartości modyfikuje także pewien stan lub ma zauważalną interakcję z funkcjami wywoływania lub światem zewnętrznym. Czytanie z pliku to obserwowalna interakcja ze światem zewnętrznym. Spełnia definicję działania niepożądanego. Odczytanie 42. elementu z pamięci globalnej byłoby również skutkiem ubocznym, chyba że tablica jest stała, ponieważ byłaby obserwowalną interakcją z innymi funkcjami, które mogą modyfikować tablicę.
źródło
Jeśli masz współużytkowany uchwyt pliku, to odczytanie pliku spowoduje przeniesienie tego uchwytu pliku do pozycji, w której przeczytałeś i pozostawi go w tej pozycji.
Jeśli masz dwa wątki z osobnymi uchwytami plików do tego samego pliku, odczyt jednego z nich nie będzie miał zauważalnego efektu ubocznego na drugim.
Jednak w obu przypadkach, podczas odczytu pamięci i odczytu plików, może wystąpić ukryty efekt uboczny buforowania systemu operatora.
źródło
Odczytywanie z pamięci nie wpływa na inne funkcje i dlatego jest wolne od skutków ubocznych. Odczytywanie z pliku zazwyczaj przesuwa wskaźnik pozycji pliku, dzięki czemu po ponownym czytaniu odczytujesz dane po tym, co już przeczytałeś, więc jedna funkcja odczytu zmienia wynik innych funkcji odczytu, co jest efektem ubocznym. Jeśli zamiast tego otworzysz, przeczytasz i zamkniesz plik za jednym razem, ten efekt uboczny zniknie, ale nie jest to możliwe w przypadku dużych plików. Dodatkowo, w zależności od sposobu otwierania pliku, może on zostać zablokowany po otwarciu, więc pierwsza próba otwarcia i odczytania pliku zakończy się powodzeniem, a kolejne próby zakończą się błędem Plik już otwarty , co znowu jest efektem ubocznym.
Utworzenie funkcji odczytu bez skutków ubocznych, która odczytuje plik za jednym razem i umożliwia wielokrotne odczytywanie w tym samym czasie, jest trudne, ponieważ istnieją funkcje zapisu plików, na które wpływ ma funkcja odczytu, a pozbycie się funkcji zapisu plików ponownie nie jest możliwe .
źródło
IO
monady?), Możesz zrobić funkcję odczytu bez skutków ubocznych.Odczytywanie ze strumienia jest już efektem ubocznym, ponieważ wynik takich funkcji, jak
isEOF
może zwrócić inny wynik po odczycie niż przed odczytem.źródło