README.md

# Reactive Elixir

Reactive Elixir is a small library to do reactive programming in Elixir. It's
main purpose is to expiriment in an academic setting. My personal goal with this
project is to run it on raspberry pi's and simulate IoT devices.

Concretly it needs to have the following features.

 * Simulate source signals (e.g., mouse location, temperature sensor value,..)
 * Create a DAG of source nodes, internal nodes, and sinks.

The library does not offer any kind of glitch freedom.

## Source vs Derived 

### Source Signal
A source signal is a signal that is reified into the runtime. For example,
Flapjax offers you the mouse position as a source signal. Because I want to
_simulate_ devices with several signals, I have decided to allow setting up a
few source signals.

We create a temperature signal using `Reactive.Signal.Source.new/4`.

```
{:ok, t} = Source.new(fn(_old_value) -> Enum.random(10..100) end, -1, 5000, :temperature)
```

The parameters are the following.

 1. The function that generates a new value with the old one as the parameter.
 2. The initial value.
 3. The time between two signal generations.
 4. The human readable name of the signal.
 
 ### Derived Signal
 
 A derived signal, as the name hints, is a signal that is derived from the value
 of another signal. These can be either source or derived signals.
 
 Assume we have the signal `t` in scope from the previous example. We can create
 a new signal based on that which generates "hot" or "cold".

```
t
|> Reactive.liftapp(&hot_cold/1)
```

The `&hot_cold/1` function takes in an integer representing the temperature and
returns "hot" or "cold" based on the value.  We can *lift* this function into a
signal world by calling `Reactive.lift/1` on it. This returns a function that
takes a Signal Integer and turns it into a String Integer.

To hook this lifted function up to the signal we need to `apply` it to the
signal. Mind you that the function that is lifted is merely a function. We need
to apply it in order for it to execute. `liftapp/2` is a shorthand for
`apply(lift(f), signal)`.

## Installation

```elixir
def deps do
  [{:reactivity, "~> 0.1.0"}]
end
```