Я в основном программист на C / C ++, а это значит, что большая часть моего опыта связана с процедурными и объектно-ориентированными парадигмами. Однако, как известно многим программистам на C ++, C ++ с годами сместил акцент на стиль функционального esque, завершившийся, наконец, добавлением лямбд и закрытий в C ++ 0x.
Несмотря на это, хотя у меня есть значительный опыт написания кода в функциональном стиле с использованием C ++, у меня очень мало опыта работы с реальными функциональными языками, такими как Lisp, Haskell и т. Д.
Недавно я начал изучать эти языки, потому что идея «без побочных эффектов» в чисто функциональных языках всегда интересовала меня, особенно в том, что касается приложений для параллелизма и распределенных вычислений.
Однако, исходя из опыта C ++, я не понимаю, как эта философия «без побочных эффектов» работает с асинхронным программированием. Под асинхронным программированием я подразумеваю любой фреймворк / API / стиль кодирования, который отправляет предоставляемые пользователем обработчики событий для обработки событий, которые происходят асинхронно (вне потока программы). Это включает в себя асинхронные библиотеки, такие как Boost.ASIO, или даже просто старый C обработчики сигналов или обработчики событий Java GUI.
Единственное, что у них общего, - то, что природа асинхронного программирования, по-видимому, требует создания побочных эффектов (состояния), чтобы основной поток программы осознавал, что обработчик асинхронного события был вызван. Как правило, в среде, подобной Boost.ASIO, обработчик событий изменяет состояние объекта, так что эффект события распространяется за пределы срока службы функции обработчика событий. Действительно, что еще может сделать обработчик событий? Он не может «вернуть» значение точке вызова, потому что нет точки вызова. Обработчик событий не является частью основного потока программы, поэтому единственный способ, которым он может оказать какое-либо влияние на реальную программу, - это изменить какое-то состояние (или другое состояние longjmp
на другую точку выполнения).
Таким образом, кажется, что асинхронное программирование - это асинхронное создание побочных эффектов. Это кажется полностью противоречащим целям функционального программирования. Как эти две парадигмы согласованы (на практике) в функциональных языках?