
On Mon, 10 Mar 2003 21:36:00 +0100, Nick Name
We don't have to waste time, just to solve the main issues and produce a clean and working implementation.
I love this sentence :-)
I propose here to join our efforts and design a robust and generic stream library, wich has to be thread-safe, and subsume MVars, Channels and M.Chackravarty's Ports.
This doesn't sound like a good plan to me --this has a scope way beyond a standard library. It is not clear at all how to do this properly. I do think it is an interesting subject, and I encourage you to pursue your ideas and create a working implementation to show and discuss. Maybe you can even work together with other people to find the right abstractions. Don't get me wrong, I think it is great to discuss these things and it is fun to have this GUI specific list. I just think that certain items shouldn't be part of the common GUI proposal. Let's keep these things seperate. In general, I think that we should only consider items that are a) well understood b) offer (just) enough functionality to implement more ambitious designs Given (b), I would even go for *less* abstraction in order to provide the raw functionalty of the platform -- don't try to protect the user at this level but offer programmers the freedom to create high level designs. All the best, Daan.
On Mon, 10 Mar 2003 18:12:19 +0100 George Russell
wrote: Well there are two approaches: (1) you provide a more complicated function which in addition to the new event, returns an IO () action which unbinds it. This is what HTk does, in general, though for many simple examples it is of course not required. (2) in many but not all cases it is possible to work out that the stream can be automatically deregistered. For example, as well as finalizers you can also forget the stream when the object is destroyed.
Exactly the same thing wich I am discussing with A.Reid in haskell-cafe; but finalizers don't "finalize" immediately in some cases, even if they might be satisfying. Moreover, there might be a different approach involving a list of "unsafePerformIO" values to uninstall the callbacks earlier, but I am not sure if it's worth the drawbacks.
=== AN IMPORTANT NOTE ===
I want to explain better what you just stated: "a callback model also has to have a way of deinstalling the callback".
If we return, together with the stream, the IO action used to unregister the callback, it could easily become of no use if we pass the stream to a new thread. We can't then know when that thread finishes to use the stream (we could pass the closing action together with the stream, anyway), so generally we HAVE to rely on garbage collection and finalizers. But this is the same thing of registering a callback wich multiplexes events to two threads, and the same issue.
=====
As usual, if there are two different approaches, each one with advantages and disadvantages, I prefer both, so the interface of a generic Stream library should provide both
getStream :: IO [a]
and
getStreamAndTheOtherThing :: (IO [a],IO ())
The former should use finalizers to deallocate any resource when appropriate, the latter could eventually use them anyway.
However, George, there are other problems with streams, wich are leading me to a conclusion; before revealing it :) , here's some sample issue:
- sometimes, the stream is produced with a synchronized model: you ask for a stream element only when you are ready to process it. This is used in gtk2 to avoid a backlog of mouse motion messages. We have to find a way (perhaps with a list of unsafeInterleaveIO results) to easily handle such cases; or maybe you already got it ?
- if we want a library wich generically models a changing state, we have to deal with three different types, and combination of those: State, Input streams and Output streams. I provide now an example of any of these categories, and of any combination of these (directly taken from the comments I wrote last night on my source code :)) -- The standard input is only an Input, it has no notion of "current" -- value
-- The standard output is only an Output
-- The current time is only a State, it makes no sense to "listen" to -- it since it's a continuous value, but you can read it at a given -- moment
-- An MVar has only State and Output
-- A Chan has only Input and Output
-- The mouse position has Input and State
-- A Port (in M.C. terminology) has Input,Output and State
CONCLUSION:
I propose here to join our efforts and design a robust and generic stream library, wich has to be thread-safe, and subsume MVars, Channels and M.Chackravarty's Ports. I am doing such a work alone to use it in my future projects, and it grows up well, but of course one thing is me, a student, doing an hobbist work, and another thing is to work together. We don't have to waste time, just to solve the main issues and produce a clean and working implementation.
An example of things to decide includes wether to use constructor classes or multiparameter type classes with functional dependencies (once stated that "we are GHC dependent anyway", to quote Axel)
My experience (and your, I guess) is that such a library can be implemented correctly in a couple of days, so there shouldn't be any problem, after some week of planning. I propose this just to avoid each stream-lover to rewrite everithing again each time. What do you think?
If so, the GUI task force will only have to be kind and use a generic layer for state handling, say a "Var" type with "getVar" and "setVar", so that we can provide an implementation wich also has streams when we are done.
If anyone (not just George) is interested, the best thing to do is to post on the haskell mailing list to ask for interested people, and then do the job. What do you think?
_______________________________________________ GUI mailing list GUI@haskell.org http://www.haskell.org/mailman/listinfo/gui