Non-Polite Mother

# npm

## timeline-monoid

2.0.9 • Public • Published

# Timeline Monoid

### Super simple yet versatile Functional Reactive Programming(FRP) framework with a minimal implementation for monoidal Timeline datatype

#### npm package:

https://www.npmjs.com/package/timeline-monoid

## Usage

### Asynchronous programming

Any time functions which is generally called "events" or "asynchronous events" are encapsulated to timeline instance, and they are composed to another timeline instance.

### Simple Mouse Draw on Canvas

Live Demo https://jsfiddle.net/5u9pLgme/8/

## Background and Rationale

Functional Reactive Programming (FRP) integrates time flow and compositional events into functional programming.

The basic idea is that a time-varying value can be represented as a function of time.

Let's step back and review where this complexity comes from. In an attempt to model real-world phenomena, we made some apparently reasonable decisions: We modeled real-world objects with local state by computational objects with local variables. We identified time variation in the real world with time variation in the computer. We implemented the time variation of the states of the model objects in the computer with assignments to the local variables of the model objects.

Is there another approach? Can we avoid identifying time in the computer with time in the modeled world? Must we make the model change with time in order to model phenomena in a changing world? Think about the issue in terms of mathematical functions. We can describe the time-varying behavior of a quantity x as a function of time x(t). If we concentrate on x instant by instant, we think of it as a changing quantity. Yet if we concentrate on the entire time history of values, we do not emphasize change -- the function itself does not change. (Physicists sometimes adopt this view by introducing the world lines of particles as a device for reasoning about motion.)

If time is measured in discrete steps, then we can model a time function as a (possibly infinite) sequence. In this section, we will see how to model change in terms of sequences that represent the time histories of the systems being modeled. To accomplish this, we introduce new data structures called streams. From an abstract point of view, a stream is simply a sequence. However, we will find that the straightforward implementation of streams as lists (as in section 2.2.1) doesn't fully reveal the power of stream processing. As an alternative, we introduce the technique of delayed evaluation, which enables us to represent very large (even infinite) sequences as streams.

This is really remarkable. Even though stream-withdraw implements a well-defined mathematical function whose behavior does not change, the user's perception here is one of interacting with a system that has a changing state. One way to resolve this paradox is to realize that it is the user's temporal existence that imposes state on the system. If the user could step back from the interaction and think in terms of streams of balances rather than individual transactions, the system would appear stateless. (Similarly in physics, when we observe a moving particle, we say that the position (state) of the particle is changing. However, from the perspective of the particle's world line in space-time there is no change involved.)

We began this chapter with the goal of building computational models whose structure matches our perception of the real world we are trying to model. We can model the world as a collection of separate, time-bound, interacting objects with state, or we can model the world as a single, timeless, stateless unity. Each view has powerful advantages, but neither view alone is completely satisfactory. A grand unification has yet to emerge.

Our world is modeled as an immutable, timeless, stateless unity from the perspective of physics

Frozen Block Universe and Human Consciousness

Conal Elliott(a developer who has contributed to early FRP) explaines

FRP is about "datatypes that represent a value over time ". Conventional imperative programming captures these dynamic values only indirectly, through state and mutations. The complete history (past, present, future) has no first class representation. Moreover, only discretely evolving values can be (indirectly) captured, since the imperative paradigm is temporally discrete. In contrast, FRP captures these evolving values directly and has no difficulty with continuously evolving values. Dynamic/evolving values (i.e., values "over time") are first class values in themselves. You can define them and combine them, pass them into & out of functions.

## timeline as a datatype that represents a first-class value over time / a stream (infinite sequence) in JavaScript

timeline : a datatype that represents a first class value over time in JavaScript / a stream (infinite sequence) / time function as a stream / world line in space-time.

### T() : timeline instance

T() is a timeline instance:

### timeline [now]

As timeline is an infinite stream of time, timeline has a (a user's perspective) current value: timeline[now], and can be easily get/set as below:

## timeline as a functor

timelinedatatype is a functor (a datatype that methods/functions always return the identical datatype, such as Array.map).

timeline has only one method/function, sync.

### timeline.sync()

timeline.sync() returns a new timeline instance that a given function applied to on every update of timeline[now] in reactive manner

timeline.sync() corresponds to Array.map, but on TimeLine.

As timeline.sync is functor:

Now, the values a and b are guaranteed to synchronize with satisfying the equation.

## timeline as a monoid

A monoid is an algebraic structure with a single associative binary operation and an identity element.

In algebra,

0 is an identiy element in +(addition) operation,

1 is an identity element in *(multiplication) operation,

Associative property

A string is also a monoid

string + string => string

appears to be associative, and identity element is "".

### identiy of timeline

timeline is a monoid, and the identity element of timeline is T or (T):

The nature of left identity: T(a) = a is especially important because we should intuitively be aware of that an instance of timeline for a given timeline instance is identical.

### timeline composition

timeline is a monoid, and composable:

### associative of timeline

timeline is a monoid, and satisfies associative law:

## Timeline composition

Here we can compose timelines.

Now we have 2 equations:

These equations can be easily implemented to a timeline code:

If we need a synchronized update of all of a,b,c which is an atomic update of [a,b,c],

The values of a,b,c are now guaranteed to synchronize with satisfying the equation.

In a practical program, in this manner, we can define dependencies of events, IO, etc., and timeline is a complete alternative of State Monad or Continuation Monad such as Promise simply because there is "no state" as discussed earlier.

## Event encapsulation

When we define a timeline with an empty argument:

is it really an empty timeline?

The fact is it is not empty because actually, we occasionally "manually" update the timeline value as

The argument of timeline in empty, Nevertheless, various inputs would happen to the timeline. In a sense, implicitly, our real-world events or time function of the world: f(t) are encapsulated to it.

Having said that. any event functions can be encapsulated to timeline instances.

They can be IO inputs or simply a timer event,

Obviously, the "custom" timelilne can be composed.

  (start1)(start2)
.sync(doSomethingFunction);


## Tiny library in around 100 lines

Timeline Monoid is a minimal library and the code is in around 100 lines

based on my other library free-monoid

https://www.npmjs.com/package/free-monoid

The latest code of free-monoid is hard-coded and included in the same module file of timeline-monoid.

## Keywords

### Install

npm i timeline-monoid

### Repository

github.com/timeline-monoid/timeline-monoid

3

2.0.9

MIT

30.9 kB

6