compute-it 0.2.2

compute-it is a library to define a lazy evaluated computation graph.
Documentation
<div align="center">

[![stable pipeline](https://gitlab.com/cyloncore/compute-it/badges/stable/pipeline.svg?key_text=stable)](https://gitlab.com/cyloncore/compute-it/-/pipelines?ref=stable)
[![dev/1 pipeline](https://gitlab.com/cyloncore/compute-it/badges/dev/1/pipeline.svg?key_text=dev/1)](https://gitlab.com/cyloncore/compute-it/-/pipelines?ref=dev/1)
[![docs](https://docs.rs/compute-it/badge.svg)](https://docs.rs/compute-it)
[![crates.io](https://img.shields.io/crates/v/compute-it.svg)](https://crates.io/crates/compute-it)
</div>

![compute-it logo](data/images/compute-it.png) compute-it
=========================================================

`compute-it` is a crate that provides a lazy evaluation of variables, with dependencies.

Development occurs in the `dev/1` branch.

Example of use
--------------

`compute-it` can be used to create computation with a static structure. In such use case, the structure of the computation does not changes, only the value of the variables.

```rust
use compute_it::*;

let v1 = Variable::<u32>::new(1);
let v2 = Variable::<u32>::new(2);
let v3 = Variable::<u32>::new(3);

// Create a new computation `c1` with `v1`, `v2` and `v3` as variables.
let c1 = Computation::<u32>::new(|(a, b, c)| a + b + c, (&v1, &v2, &v3));
println!("{} == 6", *c1.read_result());

// Change in `v1` change the result of `c1`.
v1.set(4);
println!("{} == 9", *c1.read_result());
```

Computation can also be used as input to other computation, and give access to intermediary results:

```rust
use compute_it::*;

let v1 = Variable::<u32>::new(1);
let v2 = Variable::<u32>::new(2);
let v3 = Variable::<u32>::new(3);

// Create a new computation `c1` with `v1` and `v2` as variables.
let c1 = Computation::<u32>::new(|(a, b)| a + b, (&v1, &v2));
println!("{} == 3", *c1.read_result());

// Create a new computation `c2` which uses the result of `c1` and the variable `v3`.
let c2 = Computation::<u32>::new(|(a, b)| a + b, (&c1, &v3));
println!("{} == 6", *c1.read_result());

// Change in the value `v1` also changes the result of `c2`.
v1.set(4);
println!("{} == 6", *c1.read_result());
println!("{} == 9", *c2.read_result());
```

`compute-it` can be used to create computation with a dynamic structure. In such use case, the list of variables and their value can be changed during runtime.

```rust
use compute_it::*;

let v1 = Variable::<u32>::new(1);
let v2 = Variable::<u32>::new(2);
let v3 = Variable::<u32>::new(3);

// Create a new computation `c1` with `v1` and `v2` as initial set of variables.
let mut c1 = VecComputation::<u32>::new(|v| v.into_iter().fold(0, |a, b| a + b), (&v1, &v2));
println!("{} == 3", *c1.read_result());

// Add `v3` to the set of varibles.
c1.push(&v3);
println!("{} == 6", *c1.read_result());

// Remove `v2` to the set of varibles.
c1.remove(&v2);
println!("{} == 4", *c1.read_result());

// Change the value of `v1`
v1.set(4);
println!("{} == 7", *c1.read_result());
```

Variables can also be grouped:

```rust
use compute_it::*;

let v1: Variable<i32> = 0.into();
let v2: Variable<u32> = 1.into();
let v3: Variable<i32> = 2.into();

/// Create a vec computation where the vector is made of a tuple of reference to i32 and u32 variables.
let mut c1 = VecComputation::<i32, (i32, u32, i32), markers::GroupedVariables>::new(
    |v: Vec<(&i32, &u32, &i32)>| v.into_iter().fold(0, |a, (b, c, d)| a + b + *c as i32 + d),
    (&(&v1, &v2, &v3),),
);
```

Sometime it can be needed to change the input of a computation to a different variable, without changing the rest of the structure of the computation graph. We can use `Reference` for that purpose:

```rust
use compute_it::*;

let v1: Variable<i32> = 1.into();
let v2: Variable<i32> = 2.into();

let mut ref1 = Reference::<i32>::new(&v1);

// `c1` is initialized to use `v1` as input.
let c1 = Computation::<i32>::new(|(x,)| *x, (&ref1,));
println!("{} == 1", *c1.read_result());

// After this call `c1` will use `v2` as input.
ref1.replace(&v2);
println!("{} == 2", *c1.read_result());
```