
Dear Axel,
I am also in favor of a medium level GUI interface. If I gave another impression, that is my fault. Well, Ports is very low level like gtk2hs, since it is merely a wrapper around the C functions of HToolkit.
Well, the Port library is still medium-level. For example, the call "createWindow :: IO WindowHandle", basically creates a window with a working event loop, default handlers, a canvas, automatic scroll bars and a seperate world and view domain. It basically provides the core-functionality needed for ObjectIO (or something) but no utility functions type safety, or abstraction.
but if the Clean low level layer (L) which is written in C was portable, why don't we use that layer directly? Why did Krasismir start with HToolkit?
That is a good question. Personally, I would have preferred to see a GTK port of the low-level layer of Clean This would also allow us to work together with the Clean people, they have an excellent compiler and lots of experience with GUI's, and it could foster more exchange of knowledge between both communities. Maybe Krasimir can tell us more about the issues involved? (However, I can also live with Port since it seems much smaller and more tractable than the Clean layer.) This actually brings me to another issue I have been wondering about. Why don't we use the GTK library as our portable GUI library directly? I may have missed some discussions about this, but if it is a really portable library, we can use the fruits of their labor. (Of course, it does need to give a native look and fool, I wonder whether GTK does that?)
I do not like the evolutionary approach. It will lead to an API which changes a lot.
Well, we both started out as amoebes but evolutionized into beings that use electrical signals to exchange opinions about how to create specific patterns on cathode ray tubes :-) But seriously. We are trying to create a medium-level interface. The Port approach is to create that using two layers: one core medium-level interface (Port) and a convenience layer on top of that, using abstraction, overloading etc (GIO/Htoolkit). The advantage is off course that more work is shared and less work is needed for a different platform. Furthermore, the design of the convenience layer is seperated from the implementation of the core functionality. This is more important than it looks -- I think many truly useful libraries have failed because they didn't have this distinction. This made it too hard to port the library since there were too many dependencies on the platform. I think this happened for example with TkGofer and Haggis (still a wonderfully complete and documented! library) The disadvantage might be that Port is too low-level to bind to the GTK+HS binding but I don't think that this is the case. Maybe you can say more about this later.
And the reason I'd like to have (A) as the common layer is: - We could both put an Object I/O layer on top of our libraries. If we use the same core functionality, it would enable people to easily migrate their applications from one specific backend to the common API.
The other approach, that you are proposing, is to define just one medium level interface (with abstraction and all) and to implement backends for each platform directly. The advantage is that it probably easier to support more backends. The disadavantage is that you need to do more work for a port. 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, ...]
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...]
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. ps. I am quite curious about what you think of Port. If it is high-level enough, it may serve the role of a core-functionality interface and you could create a port layer on top of gtk2hs. You can browse the interface directly at: http://htoolkit.sourceforge.net