Jestem głównie programistą C / C ++, co oznacza, że większość mojego doświadczenia dotyczy paradygmatów proceduralnych i obiektowych. Jednak, jak wielu programistów C ++ zdaje sobie sprawę, C ++ z biegiem lat przesunął nacisk na styl funkcjonalny, którego kulminacją było wreszcie dodanie lambdas i zamknięć w C ++ 0x.
Niezależnie od tego, chociaż mam duże doświadczenie w kodowaniu w funkcjonalnym stylu za pomocą C ++, mam bardzo małe doświadczenie z rzeczywistymi językami funkcjonalnymi, takimi jak Lisp, Haskell itp.
Niedawno zacząłem studiować te języki, ponieważ idea „braku efektów ubocznych” w czysto funkcjonalnych językach zawsze mnie intrygowała, szczególnie w odniesieniu do jej zastosowań do współbieżności i przetwarzania rozproszonego.
Jednak, pochodząc ze środowiska C ++, nie jestem pewien, jak ta filozofia „bez efektów ubocznych” działa z programowaniem asynchronicznym. Przez programowanie asynchroniczne rozumiem każdy styl frameworku / API / kodowania, który rozsyła procedury obsługi zdarzeń dostarczone przez użytkownika do obsługi zdarzeń, które występują asynchronicznie (poza przepływem programu). Obejmuje to biblioteki asynchroniczne, takie jak Boost.ASIO, a nawet zwykły stary C procedury obsługi sygnałów lub procedury obsługi zdarzeń GUI Java.
Jedną z nich wszystkich jest to, że natura programowania asynchronicznego wymaga tworzenia efektów ubocznych (stanu), aby główny przepływ programu mógł się dowiedzieć, że wywołano asynchroniczną procedurę obsługi zdarzeń. Zazwyczaj w środowisku takim jak Boost.ASIO procedura obsługi zdarzeń zmienia stan obiektu, dzięki czemu efekt zdarzenia jest propagowany poza okresem istnienia funkcji obsługi zdarzeń. Naprawdę, co jeszcze może zrobić moduł obsługi zdarzeń? Nie może „zwrócić” wartości do punktu wywoławczego, ponieważ nie ma punktu wywoławczego. Program obsługi zdarzeń nie jest częścią głównego przepływu programu, więc jedynym sposobem, w jaki może on mieć jakikolwiek wpływ na rzeczywisty program, jest zmiana pewnego stanu (lub innego longjmp
punktu wykonania).
Wygląda więc na to, że programowanie asynchroniczne polega na asynchronicznym wytwarzaniu efektów ubocznych. Wydaje się to całkowicie sprzeczne z celami programowania funkcjonalnego. Jak pogodzić te dwa paradygmaty (w praktyce) w językach funkcjonalnych?