
On Mon, 2012-04-02 at 04:03 +0200, Ertugrul Söylemez wrote:
Peter Minten
wrote: As I see FRP it has three components: the basic concepts, the underlying theory and the way the libraries actually work.
As far as I understand FRP (which is not very far at all) the basic concepts can, simplified, be formulated as:
* There are things which have a different value depending on when you look at them. (behaviors)
That's already specific to traditional FRP. In AFRP the value mutates. It's not a function of some notion of time. It is similar to a list. That list contains the current value as well as a description of the future of the value:
newtype SF a b = SF (a -> (b, SF a b))
The current value and the future depend on a momentary input value of type 'a' (which usually comes from another SF).
I think I understand what you're saying now. Basically instead of behaviors netwire has signal functions which are basically the same idea as simplified conduits/enumeratees. When you step (run) a signal function you get two things: an output value and a replacement for the signal function. Because the signal functions can be replaced a system of signal functions can change between steps. Netwire doesn't actually have a notion of time as such. If you need to know the current time you'll have to supply that yourself. Wires also don't run continuously, only when stepped explicitly. Where in traditional FRP you (in some libraries) could ask for the value of a behavior at any time in netwire you can only get the equivalent value (the output value of a signal function) by stepping. The big difference between netwire and traditional AFRP libraries are ArrowChoice instances which allow if-then-else and case constructions in proc notation. This simplifies programming greatly as it requires less thinking in FRP terms. When you say "Event a b = SF a (Maybe b)" you're basically saying that for netwire events are the same thing as behaviors: they're both signal functions. Events can be expressed as signal functions that sometimes have a value. If they have a value during a step the event occurs during that step. The whole system is very discrete, time isn't a primitive at all. If time plays a role it's just as an input, it's not built into something. To get something "return 1 but from second 10 onward return 2" you pass time as an input and once you see that the time is greater than 10 you can change the signal function to "arr (const 2)" to fix it to return 2, whatever the new time is. Greetings, Peter Minten