F# GUI plumbing with reactive Events
My most recent "Aha!" moment with the language is to finally wrap my head around the standard Event
module -- a sort of lightweight subset of the Reactive Extensions for .net -- while starting to do some more GUI programming in F#, which is making belated use of the GTK#/Glade spikes I made about a year ago.
It may not make much difference in the simplest cases where
naively went to
but which is equivalent to, using the Event
module,
At this point the main difference is the change in the function signature -- first, it is a real F# function rather than being forced to use the implicit cast from a fun to a delegate, even if the function signatures look compatible on the surface; second the function passed to Event.add
doesn't have the source argument (but, as shown, that can be brought in as a closure).
So that's a small win from the beginning -- but that just scratches the surface. Where it actually shines is where multiple sources of events have to be handled in much the same way. For example, given a menu containing recently accessed files, with selection meaning to re-open that file, as if they had been selected from a file open action
All the inhomogeneity of the event sources (button click, menu item activation) and their associated EventArgs
types is smoothed away by appropriate Event.map
calls and the use of closures; different validations are handled by appropriate Event.filter
or Event.choose
invocations; and then the whole ensemble is gathered together by an appropriate fold with Event.merge
as the accumulator.
True, there is nothing here that could not be achieved by making old-style handler functions for AddHandler
from equivalent appropriately composed function chains -- the path I was starting to take for this bit of plumbing before I was indirectly reminded of this feature, and dug up this series of posts from a couple of years back (so slightly dated in the details). The big difference that using the Event
module makes is that it is more expressive of intent, and separates the concerns -- general event handling plumbing vs this application's business logic -- explicitly.
1 comment :
Hi Steve. It's another Dec 25th (almost) ... finally I found your very helpful blog post. Thanks
Post a Comment