At 14:32 30-1-03 +0100, Daan Leijen wrote:
[..]
However, it is not yet clear how that level should look like. We could
take
the ObjectIO interface as our layer but I would not recommend that.
Note, this is not a critique on the ObjectIO library, I highly respect
the work
of the Clean people, and Peter van Achten in particular. However, the
Haskell
ObjectIO interface should be heavily revised to fit better in the style
of Haskell.
Right now, it is still influenced by the non-monadic uniqueness style of
Clean.
For example, the generation of identifiers (openId) is quit unsafe. In
the Haskell
tradition we would use a monadic bind to name widgets. ie.
> w <- window []
instead of
> w <- openId
> openWindow ... [ WindowId w, ...]
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
Also, if you do prefer the binding style, it is easily added to
Object I/O:
- window :: IO WindowID
- window = do {
- w
<- openId
-
window [WindowId w]
-
return w
- }
Other things are the widget attributes that are specified using
constructors. A more Haskellish
style
would use function names instead of constructors (as to be able to
abstract from them) and use type
classes for grouping them (as to prevent using illegal attributes on a
certain widget). i.e.
> w <- window [title =: "My window" ]
instead of
> w <- openId
> openWindow ... [ WindowId w, WindowTitle
w...]
Window titles are mandatory in Object I/O, so the excerpt should
read:
- w <- openId
- openWindow ... (Window "My window" [WindowId w])
The same argument applies here as above: data constructors are more
'first-class' than functions because one can do pattern-matching on them.
Also, it is more general, as the elegant TkGofer style is built easily on
top of it. For Object I/O devotees, it could be done as follows (in
Clean):
- // The class that fixes the relation between widget and attribute:
- class Atts gui att where
- addAtt :: (gui .ls .pst) (att *(.ls,.pst)) ->
gui .ls .pst
- getAtt :: (gui .ls
.pst)
-> att *(.ls,.pst)
- // 'Lift' current attribute data constructors to type constructors:
- :: WindowViewSize st = WindowViewSize` Size
- :: WindowHScroll st = WindowHScroll`
ScrollFunction
- /* Instantiate the proper relations (note that view size and scroll
bar
- are proper Window attributes, but for Dialogs only view
size is valid.
- */
- instance Atts (Window c) WindowViewSize | Controls c where ...
- instance Atts (Window c) WindowHScroll | Controls c where ...
- instance Atts (Dialog c) WindowViewSize | Controls c where ...
- // Convenient shorthand for addAtt:
- (<==) infixl :: (gui .ls .pst) (att *(.ls,.pst))
-
-> gui .ls .pst | Atts gui att
- (<==) w a = addAtt w a
- // Now one can set size and scroll attribute for a window...
- w = Window "Hi there" NilLS []
- <== WindowViewSize` {w=100,h=200}
- <== WindowHScroll`
(stdScrollFunction Horizontal 100)
- // ...and *only* the size for a dialog...
- d1 = Dialog "Hi there" NilLS [] <== WindowViewSize`
{w=100,h=200}
- // ...but setting scrollbar won't type check...
- d2 = Dialog "Hi there" NilLS [] <== WindowHScroll`
-
(stdScrollFunction Horizontal 100)
This is basically what I am trying to do in the GIO library.
However, even than, there
are still tons of other design decisions to make, I wonder whether
consensus can ever
be reached.
All the best,
Daan.
The above is not a critique on Port or GIO (honest!). I just wanted to
explain part of the design reasons for Object I/O and show that it
supports elegant ideas such as advocated by Daan.
Regards,
Peter