
Today I sat down and had a think about this problem. After reading about various FRP systems (Yampa et al) I had a few ideas in my head. The main idea is that I want to be able to draw lines and curves and so forth, and I want to add them to and remove them from the display at various times, and move them around, change their colour and opacity, etc. I also want to be able to run one piece of animation, and then another, and then another. So I want some sort of sequencing primitives. I had a go at writing what I thought the interface might look like. (Fortunately, I made no attempt to *implement* it - otherwise I would doubtless have wasted huge amounts of time implementing something that isn't designed right yet!) Unfortunately Haskell doesn't really provide a way to write an "interface", and then write the implementation behind it seperately somewhere else. So the "code" I wrote wasn't actually compilable at all, but it was useful to sketch something out. My initial idea was that I could have some kind of monad for controlling adding and removing stuff. The monad could provide an "add" action that adds a visual object to the frame and returns a unique ID. Then you could have a "remove" action that removes the specified ID again. And a "wait" action that makes the display stay the same for so many seconds. (But the visual objects may internally be animated.) Then I hit upon the idea that maybe one thread of control could "spawn" a second one - so that for example one thread could generate a bunch of snowflakes raining down the screen while a seperate thread rotates a geometric figure in the center. Or something. Of course, these "threads" have no need (or use) for actually running concurrently - they are only "concurrent" in the sence that they both affect the same frame, rather than their actions happening one after another on consecutive frames. Next I got to thinking that maybe these threads of control might need to communicate for synchronisation. E.g., when a rotating line reaches 90° with another line, a signal is sent to another thread, which then adds another visual element or stops the animation or something. The parent thread *could* algebraicly _compute_ what time this will happen, but sending a signal is much simpler. (E.g., if you change the speed of an animation, the threads still stay synchronised without you having to remember to adjust parameters in your calculations all over the place...) There's still one little problem though. The "threads of control" are for sequencing stuff. They are inherantly discrete; *add* this thing, *remove* this other thing, *send* this signal, *wait* to receive a signal, etc. But something like, say, rotating a line, is inherantly continuous. So there's a discrete system for sequencing stuff - which I seem to have worked out fairly well - and there also needs to be a continuous system for doing all the things with are smooth functions of time. So maybe the continuous stuff should just be a type alias to a regular Haskell function? Ah, but wait... I said I might want to send a signal when an animation reaches a specific stage, right? So these "functions" need to do more than just map time to some other variable; they need to be able to send signals. And hey, actually, what are the chances of a time sample exactly lining up with the instant that the notable event occurs? How do I want to handle that? ...and at this point, it was time to go home! :-D