Rozumiem atrakcyjność czystych języków funkcjonalnych, takich jak Haskell, gdzie można śledzić efekty uboczne, takie jak we/wy dysku za pomocą monad.Co liczy się jako efekt uboczny? Dlaczego alokacja pamięci nie jest efektem ubocznym?
Dlaczego nie wszystkie wywołania systemowe są uważane za efekty uboczne? Na przykład przydział pamięci sterty (który jest automatyczny) w Haskell nie jest śledzony. A przydział sterty może być efektem ubocznym, chociaż nie jestem pewien, czy byłby użyteczny. Oba zmieniają ogólny stan systemu.
Więc gdzie jest linia narysowana, co jest efektem ubocznym, a co nie? Czy jest to po prostu to, co jest najbardziej "użyteczne"? Czy istnieje bardziej teoretyczny fundament?
Myślę, że najprostszą odpowiedzią jest to, że jeśli alokacja byłaby efektem ubocznym, bardzo niewiele rzeczy byłoby "czystych", co zmniejsza użyteczność tego pojęcia. Purity nie ma jednej uniwersalnej rygorystycznej definicji. Mogę sobie wyobrazić język, który * zrobił * traktował alokację jako efekt uboczny i zarządzał nim przez system typów, co może być bardzo przydatne w systemach z niewielką ilością pamięci (np. Systemy wbudowane), ale nie znam żadnej taki język obecnie. –
Alokacja pamięci jest efektem ubocznym, jeśli chcesz kontrolować, kiedy to się stanie. Zobacz opakowania owijające IORef/STRef/FunPtr. Chodzi o to, że jeśli dzieje się to automatycznie, możesz zaufać kompilatorowi, by był inteligentny, więc Haskell nie zmusza cię do tego, by się tym martwić. –
@AlexisKing Jako ktoś, kto od czasu do czasu musi napisać kod dla systemów wbudowanych, byłby to naprawdę interesujący język do wdrożenia. Wyobrażam sobie, że można go napisać jako DSL w Haskell, ale byłby fajny jako samodzielny język, który kompilował bardzo wydajnie. – bheklilr