At 18:36 31-1-03 +0100, Daan Leijen wrote:
Dear PeterObject I/O can easily be extended with typed identification values, in the same way as has been done for receivers (RId m) and (R2Id m r). The binding of typed identification value and the GUI object is at the data constructor.
- This issue has nothing to do with monads, but is rather a design decision how to identify GUI elements. One particular disadvantage of the
- w <- window []
- style is that GUI creation is an (opaque) action, rather than a first-class description of the GUI. Identification values become available only after creation of GUI elements, which is less convenient than knowing them beforehand. The only 'danger' is forgetting to associate the identification value with the window, but the same problem exists with the other style:
- w <- window [] -- window identified by w
- ...
- close w -- window identified by w destroyed
- ...
- setTitle w "Hi there" -- unbound
There is more to this. Since ID's are untyped, it happened to me a few times that I attached the wrong id to the
wrong widget. Each widget is later accessed with an untyped ID, that may be connected
to a completely different widget kind. With the monadic style, not an identifier
is returned but the typed entity itself and thus all further access is also checked.
In this respect, I believe that a medium-level library should
- Offer as much type safety as possible without sacrificing flexibility or give incomprehensible type errors. That's why GIO doesn't use multiple parameter type classes to to implement attributes as in your example :-). This is also what I like ObjectIO -- it uses little overloading (but a fairly difficult GUI type).
- The "dynamic" ness of the library is also used to circumvent the problem that one wants to refer to a window before it is created, for example while specifying the layout of buttons in a window. In GIO, the layout can be set later, after the creation of the child controls.
- > do w <- window [title =: "Demo"]
- > q <- button [text =: "Quit", on command =: close w]
- > set w [layout =: center q]
- Same story for event handlers. I am not sure though how inconvenient this can be when creating larger applications but I feel that the extra type safety is worth the inconvenience. (Btw, layout is another dark area: what does it mean for example when a button is put next to itself (q <<< q), or when a button
- created in some window is layed out in another?)