Skip to content

Chapter 1: FRP is like Spreadsheet

Another familiar example of something fundamentally designed to keep its versions perfectly synchronized is the spreadsheet.

And the FRP library being introduced here, Timeline , will be easier to understand if this spreadsheet principle is kept in mind.

Timeline provides binary operations to utilize the state management

Section titled β€œTimeline provides binary operations to utilize the state management”

In Functional Programming, everything is an expression or operation. Accordingly, Timeline library provides binary operations for the reactive state management .

This binary operation corresponds to an operation in spreadsheet apps.

image

image



'a -> Timeline<'a>
let counter = Timeline 0

Consider the Timeline as a specific container for a value, similar to a Cell in spreadsheet apps.

image


('a -> 'b) -> (Timeline<'a> -> Timeline<'b>)
('a -> Timeline<'b>) -> (Timeline<'a> -> Timeline<'b>)

When the binary operator: is TL.map,

let double = fun a -> a * 2
let timelineA = Timeline 1
let timelineB =
timelineA |> TL.map double
log (timelineB |> TL.at Now)
// 2

This code for the binary operation simply corresponds to the basic usage of spreadsheet apps

image

This is the identical structure of:

let double = a => a * 2;
let listA = [1];
let listB =
listA.map(double);
console.log(listB);
// [2]

image

We could recognize the array [2] is identical to the Cell and Value 2 of a spreadsheet; however, the spreadsheet and Timeline maintain a double relationship as values change over the timeline .


'a -> Timeline<'a> -> unit
let timelineA = Timeline 1
timelineA |> TL.next 3
log (timelineA |> TL.at Now)
// 3

image


The update to timelineA will trigger a reactive update of timelineB according to the rule defined by the binary operation.

image

let double = fun a -> a * 2
// β‘  initialize timelineA
let timelineA = Timeline 1
// confirm the lastVal of timelineA
log (timelineA |> TL.at Now)
// 1
// β‘‘ the binary operation
let timelineB =
timelineA |> TL.map double
// confirm the lastVal of timelineB
log (timelineB |> TL.at Now)
// 2
//=====================================
// β‘’ update the lastVal of timelineA
timelineA
|> TL.next 3
// update to timelineA will trigger
// a reactive update of timelineB
// confirm the lastVal of timelineA & timelineB
log (timelineA |> TL.at Now)
// 3
log (timelineB |> TL.at Now)
// 6