Функциональное программирование на основе событий

У меня возникают проблемы при написании кода GUI, управляемого событиями, в функциональном стиле с использованием Clojure и Seesaw. В частности, я не могу понять, как передать состояние программы без использования глобальных переменных или какого-либо другого неприятного взлома. Мой нынешний подход выглядит примерно так:

(defn event-handler [gui-state event]
   (update-gui! (get-new-state gui-state event)))

(defn update-gui! [gui-state]
   (remove-all-listeners (gui-state :button))
   (seesaw.core/listen (gui-state :button)
                       :action
                       (partial event-handler gui-state)))

Он устанавливает прослушиватель событий в соответствующем компоненте с частично примененной функцией для улучшения состояния и обновления графического интерфейса, включая удаление старого прослушивателя. Хотя кажется, что это работает, мне это не очень нравится, отчасти потому, что я не могу передать сам слушатель в состоянии (так как он не создан до тех пор, пока я уже не определил состояние), поэтому удаление старого слушателя требует удаление всех слушателей, которые могут вызвать проблемы по мере роста программы.

Самое близкое решение, которое я нашел в Интернете, находится в этом ответе, но я не знаю, как обрабатывать события как поток, как это показано. Я уверен, что должно быть лучшее решение, чем мой нынешний подход, но я не могу понять, что.

Может кто-нибудь показать мне, как я могу реагировать на события пользовательского ввода, все еще следуя функциональному стилю?

1 ответ

Решение

Потоки из связанного ответа кажутся аналогом каналов core.async.

Вместо удаления всех слушателей каждое событие может быть передано в канал, в который помещены подробности события. Этот же канал должен идти к логическому обработчику кнопки, откуда он будет повторно взят.

Другие вопросы по тегам