Following is the most comprehensible description I have found:

For each signal in a FrTime program, we construct a signal data structure. The data structure contains an update procedure, which computes the signal’s value, and a mutable field that stores the signal’s most recently computed value. Thus, there is an implicit notion of real time, which the system exhibits directly.

A special thread called the signal manager is responsible for keeping signals current.
It maintains an explicit graph of the dependencies between signals. For example, when we evaluate (even? seconds), the resulting behavior depends on seconds, so the signal manager needs to recompute it whenever seconds changes.

The manager uses an asynchronous message queue to control all computation. For example, when seconds changes, the manager sends itself an update message for each dependent signal. When it dequeues such a message, it recomputes the corresponding signal. This in turn may demand recomputation of yet more signals, so evaluation proceeds recursively in a breadth-first, bottom-up manner.

Some signals require re-evaluation after intervals of time. For example, seconds needs to update once every second. The signal manager supports this capability by keeping a prioritized “alarm” queue, which maps signals to update times. On each iteration of its processing loop, the manager checks whether the current time exceeds the earliest alarm in the queue. If so, it executes the corresponding update; otherwise, it sleeps until either the next alarm or the arrival of a message. Our asynchronous message-passing library makes this easy by providing a receive construct with a fine (millisecond-granularity) timeout parameter.

Our evaluation algorithm employs two main optimizations. First, if recomputing a signal does not change its value, then the manager does not schedule updates for the dependents. Second, to avoid scheduling the same signal for multiple updates, we give each signal a flag to indicate whether it has already been scheduled. The manager sets this flag before sending an update message and clears it after updating the signal. (If the flag is already set, the manager does not send the message.)

It is from "FrTime: Functional Reactive Programming in PLT Scheme" by Cooper and Krishnamurthi

By on 10/19/2006 10:35 PM ()

Hi falcon,

There are many approaches to architecture and design patterns in this space. I have the feeling that the fully declarative approach (ala Fran) is hard to make work, though very beautiful in principle. The other toolkits (Yampa and SuperGlue) I'm not so familiar with.

I tend to take a mixed functional/imperative approach here, e.g.

  • use IEnumerables to capture any process that sucks on large data sources such as files and databases
  • Implement algorithms so they are "open", e.g. a functional implementation of a core algorithm emitting imperative events through a set of IEvent parameters.
  • if you have to respond to changes in data from external datasources, then at some point those responses are modelled as events. If you can hook those up to a functional/declarative description about what to _do_ when those events fire, then that is excellent, even if the actual execution of events is imperative.

I find F# excellent at representing these different architectural possibilities. I think there is real scope for developing mixed functional/imperative reactive programming techniques in the context of F#.

Don

By on 10/14/2006 10:08 AM ()
IntelliFactory Offices Copyright (c) 2011-2012 IntelliFactory. All rights reserved.
Home | Products | Consulting | Trainings | Blogs | Jobs | Contact Us | Terms of Use | Privacy Policy | Cookie Policy
Built with WebSharper