To pytanie teoretyczne, ale po wielu latach programowania w tym, co teraz zdaję sobie sprawę, że jest to „normalna” technika imperatywna, wykorzystująca głównie C ++, odkryłem ten inny świat programowania funkcjonalnego, na który przypadkiem natknąłem się podczas przypadkowej nauki JavaScript.
Doprowadziło mnie to do zastanowienia się, czy można technicznie zastąpić dowolny kompletny program zorientowany na państwo inną implementacją, która jest czysto funkcjonalna i bez stanu?
To intrygujący pomysł i muszę przyznać, że w funkcjonalnym programowaniu jest jasność i elegancja, które naprawdę zaskoczyły mnie.
Odpowiedzi:
Krótka odpowiedź: tak. Według Wikipedii równoważność rachunku lambda do maszyn Turinga jako uniwersalnego modelu obliczeń wykazał w 1937 r. Alan Turing. Model obliczeniowy maszyny Turinga jest tym, o czym zwykle myślisz, mówiąc o programowaniu imperatywnym lub stanowym, a rachunek lambda jest matematyczną formalizacją „czysto funkcjonalnego programowania”.
Przypuszcza się, że każdy skuteczny model obliczeń jest w stanie wykonać te same obliczenia co maszyna Turinga i odwrotnie. Nazywa się to tezą Turinga . Nie można jednak udowodnić tego przypuszczenia z powodu mniej lub bardziej intuicyjnego terminu „efektywny model obliczeń” (może ktoś wymyśli nowy model w przyszłości?)
źródło
W jakimkolwiek systemie dynamicznym „stan” sprawia, że na teraźniejszość ma wpływ przeszłość lub przyszłość (strzała czasu nie jest zagadnieniem matematycznym, tylko ograniczeniem fizycznym).
Czy masz coś do zapamiętania, czy to zależy od tego, co zrobiłeś, masz stan.
System bez stanu nie jest „dynamiczny”: jest tylko funkcją kombinatoryczną. To może nie mieć stanu, ale - aby uzyskać różne wyniki - potrzebuje stanu, który w jakiś sposób zostanie dostarczony.
Teraz, w zależności od modelu obliczeniowego, do którego się odwołujesz, stan może być reprezentowany jawnie (w postaci zmiennej) lub niejawnie (w postaci „adresów zwrotnych”).
kiedy to robisz,
fna(fnb(x))
podajesz stan fnb, który z kolei wytworzy stan dla fna. Wynika to z faktu, żex
istnieje przed wywołaniem fnb (więc pochodzi z własnej „przeszłości”).To nie jest kwestia „stanu wyjścia” lub „stanu nie istnieje”. Jest to kwestia „zależy mi” lub „nie”.
źródło
Stan oznacza zdolność do reagowania na obecny bodziec w sposób zależny od bodźców z przeszłości, a nie tylko od bodźca obecnego.
Czysto funkcjonalne programy to tylko funkcje. Tak więc dla praktycznych zastosowań czysto funkcjonalny program wprowadza parę (old_state * present_stimulus) i wyprowadza parę (new_state * present_response). Potrzebny jest zewnętrzny, stanowy „looper”, aby czekać na następny bodziec i propagować stan.
Czysto funkcjonalny program nie ma własnego stanu i nie może być używany bezpośrednio w praktycznych aplikacjach.
Dlatego żadnego programu zorientowanego na państwo nie można zastąpić inną implementacją, która jest czysto funkcjonalna i bez stanu.
źródło
Możesz uniknąć jawnego stanu zmiennego, o ile nie będziesz musiał wchodzić w interakcje ze światem zewnętrznym.
W JavaScript, aby Twój program miał efekt wykraczający poza podejmowanie cykli procesora, musisz zmodyfikować obiekt Dom lub Window, a te API są stanowe. Ale przypuszczam, że można utworzyć opakowanie, które przekazuje obiekty Dom i Window jako parametry do kodu JavaScript, a następnie otrzymuje nowe dane wyjściowe Dom / Window. To izolowałoby kod JavaScript od stanu zmiennego.
Oczywiście nadal polegasz na stanie, ponieważ okno przeglądarki i DOM są z natury stanowe. Każda aplikacja interaktywna jest z natury stanowa, ale nadal możesz tak ustrukturyzować swój kod, aby zminimalizować jawny stan.
Inne pytanie dotyczy tego, czy to dobry pomysł. Nawet Haskell, który z założenia jest czysto funkcjonalnym językiem, zawiera monadę „stanową”, która pozwala symulować stan zmienny. To pokazuje, że jawny stan mutable czasami jest naprawdę pożądanym wzorcem.
źródło
Zastanów się, jak zaimplementujesz „maszynę stanową” w języku programowania bez stanu.
Prawdopodobnie mógłbyś to zrobić, ale ostatecznie użyłbyś nazw funkcji jako pamięci. Skończyło się na gobblyday:
źródło