What is Functional Reactive Programming?

  • Also known as data-flow programming, builds on concepts of Functional Programming
  • Is a combination of Functional Programming and Reactive Programming
  • It allows you to react to data changes over time using declarative, functional transformations

Think of it like a spreadsheet:

  • If cell A changes, cell B (which depends on A) updates automatically.
  • You don’t need to manually update cell Bβ€”the relationship is declared and updates reactively.
  • FRP works similarly: data flows automatically based on dependencies.

FRP allows us to express data flows over time using declarative, functional transformations.

πŸ”— Further Reading: Wikipedia - Functional Reactive Programming


Differences Between FRP and FP

FeatureFunctional Programming (FP)Functional Reactive Programming (FRP)
FocusData transformationData flow over time
Execution ModelApplies transformations on existing dataContinuously reacts to new data
State ManagementStateless, pure functionsReactive streams manage state changes
MutationAvoids mutation, but still works on fixed dataAvoids mutation, and data is event-driven

Example

import Combine
 
// 1. Define a reactive stream for user input
let userInput = PassthroughSubject<String, Never>()
 
// 2. Apply functional transformations (functional part)
let validatedInput = userInput
    .filter { $0.count > 3 } // Only allow strings longer than 3 characters
    .map { $0.uppercased() } // Convert to uppercase
 
// 3. Subscribe to changes (reactive part)
let cancellable = validatedInput
    .sink { print("πŸ“’ Valid Input Received: \($0)") }
 
// 4. Simulate user typing (reactive updates)
userInput.send("Hi")    // No output (filtered out)
userInput.send("Hello") // Output: πŸ“’ Valid Input Received: HELLO
userInput.send("Swift") // Output: πŸ“’ Valid Input Received: SWIFT
 

Why is this FRP?
βœ… Functional β†’ Uses filter and map to transform data.
βœ… Reactive β†’ The subscriber automatically reacts to new values.
βœ… Event-Driven β†’ The program reacts as input changes, instead of executing once.