Event Driven Functional Programming

I am having trouble writing event driven graphical code in a functional style using Clojure and Seesaw. In particular, I can’t understand how to transfer the state of a program without using globals or any other unpleasant hack. My current approach looks something like this:

(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))) 

It installs an event listener in the appropriate component with a partially applied function to promote the state and update the gui, including deleting the old listener. Although this seems to work, I really don't like it, partly because I cannot pass the listener itself in state (since it was not created until I already determined the state), so deleting the old listener requires deleting all listeners, which can cause problems as the program grows.

The closest solution I found on the Internet is in this answer , but I don't know how to handle events as a stream, as it shows. I am sure there should be a better solution than my current approach, but I cannot understand that.

Can someone show me how I can respond to user input events while still following the functional style?

+5
source share
1 answer

The streams from the linked response seem to be analogous to the core.async channels.

Instead of deleting all listeners, each event can take place in a channel in which event data is indicated. The same channel should go to the logical button handler, where it will be reused.

+1
source

Source: https://habr.com/ru/post/1206844/


All Articles