---
# System prepended metadata

title: Change-Sourced Values

---

## Change-Sourced Values

**Purpose:** Capture a structured history of changes applied to some value.

In the following example, we build a data pipeline, capturing all transformations without actually running any of them. We do this by lifting the raw value into a wrapper object that allows you to _treat it_ like a raw value while silently tracking transformations made to it.

```jsx!
const phrase: Input = input('hey');
const loud: Derived = upper(phrase);
const angry: Derived = concat(loud, '!!!');
```

Or more concisely:

```jsx!
const angry = map(
    input('hey'),
    upper,
    concat('!!!'),
)
```

A derived value only computes when it is called.
```jsx!
angry() === 'HEY!!!'
```

The history of all operations is preserved on the underlying object
```jsx!
angry = {
 key: 'concat',
 args: [
  {
   key: 'upper',
   args: input('hey'),
  },
  '!!!'
 ]
}
```

We'll want to guarantee we've capture the complete history of operations during the dispatch and that no information was lost. It's (almost) possible to acheive this by dispatching under a context where unwrapping the tracked input throws a runtime error.

For example -

```jsx!
function foo(txt: Input<string>) { /* black box */ }

noUnwrap(() => {
   foo(input('hey')) === derived(326); 
   // No error means the input was never unwrapped - 
   // we have a complete computation.
});
```

Where did `326` come from? `derived` captured all the operations - we can have a look.

```ts!
output = {
    key: 'reduce',
    args: [
        { key: 'sum' },
        {
            key: 'map',
            args: [
                { key: 'charCode' },
                {
                    key: 'split',
                    args: [
                        '',
                        input('hey'),
                    ]
                }
            ]
        }
    ]
}
```

This resembles a sort of "expression AST" - built only from "values of interest".

We can see the following operation chain took place:

```ts!
'hey'.split('').map(c => c.charCodeAt(0)).reduce(sum);
=== 326
```

With this information, we could theoretically *reproduce the output* of this function in any language. It's important to understand that this is different than transpiling the entire function in the case where static or otherwise irrelevant actions are taken.

In practice, this wouldn't apply to a simple, pure operation like the contrived example above - but maybe a foreign function we care to introspect the behavior of.

Capturing these operations may allow us to:
 1. Efficiently recompute only the interesting bits of a code path
 2. Serialize / move the computation to other languages or environments

Experiments will determine if there's any utility here, but I think it's worth pursuing. I have some use-cases in mind, but we'll have to explore those in a follow up.


**Sidenote:** If only we had a pipe operator 🙁 (currently a stage-2 proposal in JS).

```jsx!
const angry =
    input('hey')
    |> upper
    |> concat '!!!'
```

As an alternative, I would suggest we introduce the `.map` operator to our wrapper class.

```jsx!
const angry =
    input('hey')
    .map(upper)
    .map(concat('!!!'));
```
