Functional reactive programming (FRP) combines reactive programming with functional ideas. It models time-varying values as signals, also called behaviors: when one value depends on another, changes propagate automatically. Events can occur, change, repeat, or disappear, so they can be treated as time-dependent values and bound to reactions. section 2.1.2
A reactive network composes signals with actions. Functional reactive streams express a closely related data-flow model: continuous, time-ordered event streams can be mapped, merged, divided, or zipped into new streams, and changes or absences can trigger actions. This makes the approach useful for GUI behavior, complex business logic, and interoperability code. section 2.1.2 section 3.1.4
Build a pipeline around explicit flow of changing values:
- Produce readings continuously from an external source rather than placing all work in a single sequential control script. section 3.1.4
- Transform or normalize each value in a focused operation before downstream processing. section 3.1.4
- Consume each emitted value in a monitor that stores it, validates it, logs failures, raises alarms, and yields a result. section 3.1.4
Temperature-monitoring flow
A thermReadings stream reads an outside thermometer once a second and yields each reading. A thermMonitor stream receives each reading, stores it, validates temperature bounds, logs and raises an alarm on failure, then yields the validation result. The stream separates value production from monitoring reactions while preserving a direct flow from sensor input to external notification. section 3.1.4
FRP can also serve as an architectural boundary. An interoperability bus may be implemented with an FRP library and connect database and GUI accessors, while the wider application relates presentation, business logic, database, initialization, configuration, and global state through explicit component relations. section 3.2.3
Listing 3.6 Thermometer monitor stream
Stream: thermMonitor #1
Description: temperature monitor
Given: for @reading in thermReadings #2
Store @reading #3
validateTemperature(@reading), #4
Result: @result
If @result == (Failure, @message) Then #5
Log @reading
Raise alarm @message
Yield @result #6
Scenario: validateTemperature #7
Description: validate temperature
Parameters: (@time, @temp, @therm)
Invocation: on call
If @temp < 263.15K Then
Return (Failure, "Outside T < than bound for " + @therm)
Else If @temp > 323.15K Then
Return (Failure, "Outside T > than bound for " + @therm)
Else Return Success
Inspect the monitor stream to see one emitted reading pass through storage, validation, failure handling, and result emission. section 3.1.4
