
I think I've pointed out that the main difference between GIO and HTk is that HTk uses composable events, while GIO, like most other Haskell GUI's (including GTk+hs) use callbacks. Now of course I'm biased, and I prefer events to callbacks, but I appreciate the arguments that have been made that including composable events in a GUI would simply involve adding too much heavy machinery which doesn't have anything to do with graphics. But I think I have a solution to this, which I would like to propose. This is that a GUI standard specify events, but *doesn't* specify that they be composable. Then they would be trivial to implement, and still (in my opinion) be better than callbacks. Also systems like HTk could of course add an extra module which did provide the composition operators. So, in detail, the GUI standard should have a new type Event a which means "Event carrying a value a". To generate for example something like a button click event we could have a function clicked :: Clickable widget => widget -> IO (Event ()) Thus, after this function is called, the returned "event" would happen each time the user clicks the button. A mouse click event might, for example, have type (Event (Int,Int)) giving the co-ordinates of the mouse pointer at the time of the click. To "listen" for events, two functions would be provided: sync :: Event a -> IO a which blocks until the event happens (or returns immediately if a queued occurence of this event has already happened), and setCallBack :: Event a -> (a -> IO ()) -> IO () which added an action to be performed each time the event happens. There are questions to be asked about what happens when you have multiple consumers of the same event. I think it should be guaranteed that when an event happens, only one consumer gets to hear about it, but which does not perhaps need to be specified. (I don't think this is very likely anyway.) Summary ------- Advantages over Composable Events. easier to implement. Advantages over callbacks: can easily be extended to composable events the "sync" operator is more powerful than callbacks (without being particularly hard to implement). For example, I think all or at least most of the call-back-based solutions to the "simple GUI Example" at John Meacham's page http://repetae.net/john/computer/haskell/gui/ contain the following bug: if the user clicks twice very rapidly on the button, the second click will be ignored. In general the click-handling routines can run concurrently, perhaps modifying common shared data, and leading to all sorts of trouble, unless the user uses locks. It seems clear that what is wanted here is sync, not callbacks.