read-dependencies now correctly recorded (i think)
This commit is contained in:
parent
7a5b9d4f38
commit
614e6c0fdb
1 changed files with 82 additions and 51 deletions
|
|
@ -1,99 +1,130 @@
|
||||||
import { pretty } from "../util/pretty.js";
|
import { pretty } from "../util/pretty.js";
|
||||||
import { inspect } from "node:util";
|
import { deepEqual } from "../util/util.js";
|
||||||
|
|
||||||
// UUID -> Computation<a> -> Slot<a>
|
// UUID -> Computation<a> -> Slot<a>
|
||||||
const newSlot = uuid => computation => ({
|
const newSlot = uuid => computation => ({
|
||||||
overwrites: uuid,
|
overwrites: uuid,
|
||||||
computation,
|
computation,
|
||||||
// depth: 1,
|
// depth: 1,
|
||||||
// [inspect.custom]: (depth, options, inspect) => options.stylize(`newSlot(${inspect(uuid)})(${inspect(computation)})`, 'special'),
|
|
||||||
});
|
});
|
||||||
|
|
||||||
// a -> Computation<a>
|
// a -> Computation<a>
|
||||||
const newValue = val => ({
|
const newValue = val => ({
|
||||||
kind: "value",
|
kind: "value",
|
||||||
out: val,
|
out: val,
|
||||||
// [inspect.custom]: (depth, options, inspect) => options.stylize(`newValue(${val})`, 'special'),
|
|
||||||
});
|
});
|
||||||
|
|
||||||
const id = x => x;
|
|
||||||
|
|
||||||
// Slot<a> -> Computation<a>
|
// Slot<a> -> Computation<a>
|
||||||
const read = slot => ({
|
const read = slot => ({
|
||||||
kind: "transformation",
|
kind: "read",
|
||||||
in: slot,
|
slot,
|
||||||
fn: {
|
|
||||||
kind: "value",
|
|
||||||
out: id,
|
|
||||||
},
|
|
||||||
out: slot.computation.out,
|
out: slot.computation.out,
|
||||||
// [inspect.custom]: (depth, options, inspect) => options.stylize(`read(${inspect(slot)})`, 'special'),
|
|
||||||
});
|
});
|
||||||
|
|
||||||
// Computation<a> -> Computation<a -> b> -> Computation<b>
|
// Computation<a> -> Computation<a -> b> -> Computation<b>
|
||||||
const transform = input => fn => {
|
const transform = input => fn => {
|
||||||
// console.log("transform...", "input:", pretty(input), "fn:", pretty(fn));
|
|
||||||
const output = fn.out(input.out);
|
const output = fn.out(input.out);
|
||||||
if (input.kind === "value") {
|
if (input.kind === "value") {
|
||||||
// our input had no read dependency, thus likewise our output does not:
|
// optimization: sandwich everything together
|
||||||
return {
|
return {
|
||||||
kind: "value",
|
kind: "value",
|
||||||
out: output,
|
out: output,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
// console.log("transforming the transformation...");
|
|
||||||
return {
|
return {
|
||||||
kind: "transformation",
|
kind: "transformation",
|
||||||
in: input.in,
|
in: input,
|
||||||
// transform the transformation:
|
fn,
|
||||||
fn: transform(input.fn)(newValue(origFn => {
|
|
||||||
const descr = `${fn.out.name} ∘ ${origFn.name}`;
|
|
||||||
return { [descr]: x => fn.out(origFn(x)) }[descr];
|
|
||||||
})),
|
|
||||||
out: output,
|
out: output,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const counterOne = newSlot(Symbol('counter'))(newValue(1));
|
const verifyComputation = (computation, indent=0) => {
|
||||||
|
const printIndent = (...args) => {
|
||||||
|
console.log(" ".repeat(indent*2), ...args);
|
||||||
|
}
|
||||||
|
const compare = (a,b, kind) => {
|
||||||
|
if (typeof a === 'function' && typeof b === 'function') {
|
||||||
|
printIndent("cannot compare functions", `(${kind})`);
|
||||||
|
}
|
||||||
|
else if (deepEqual(a, b)) {
|
||||||
|
printIndent(`ok (${kind})`);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
printIndent(`bad (${kind})`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (computation.kind === "value") {
|
||||||
|
compare(1, 1, "value");
|
||||||
|
}
|
||||||
|
else if (computation.kind === "read") {
|
||||||
|
compare(computation.out, computation.slot.computation.out, "read");
|
||||||
|
}
|
||||||
|
else if (computation.kind === "transformation") {
|
||||||
|
compare(computation.fn.out(computation.in.out),
|
||||||
|
computation.out, "transformation");
|
||||||
|
|
||||||
const valueOne = read(counterOne);
|
verifyComputation(computation.in, indent+1);
|
||||||
|
verifyComputation(computation.fn, indent+1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const getReadDependencies = computation => {
|
||||||
|
if (computation.kind === "value") {
|
||||||
|
return new Set();
|
||||||
|
}
|
||||||
|
else if (computation.kind === "read") {
|
||||||
|
return new Set([computation.slot]);
|
||||||
|
}
|
||||||
|
else if (computation.kind === "transformation") {
|
||||||
|
return new Set([
|
||||||
|
...getReadDependencies(computation.in),
|
||||||
|
...getReadDependencies(computation.fn),
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
console.log(pretty({valueOne}));
|
|
||||||
|
|
||||||
const inc = x => x + 1;
|
const inc = x => x + 1;
|
||||||
|
|
||||||
const onePlusOne = transform(valueOne)(newValue(inc));
|
// const counterOne = newSlot(Symbol('counter'))(newValue(1));
|
||||||
|
// const valueOne = read(counterOne);
|
||||||
|
// console.log(pretty({valueOne}));
|
||||||
|
// const onePlusOne = transform(valueOne)(newValue(inc));
|
||||||
|
// console.log(pretty({onePlusOne}));
|
||||||
|
// const onePlusOnePlusOne = transform(onePlusOne)(newValue(inc));
|
||||||
|
// console.log(pretty({onePlusOnePlusOne}));
|
||||||
|
|
||||||
console.log(pretty({onePlusOne}));
|
// verifyComputation(valueOne);
|
||||||
|
// verifyComputation(onePlusOne);
|
||||||
|
// verifyComputation(onePlusOnePlusOne);
|
||||||
|
|
||||||
const onePlusOnePlusOne = transform(onePlusOne)(newValue(inc));
|
|
||||||
|
|
||||||
console.log(pretty({onePlusOnePlusOne}));
|
const priceSlot = newSlot(Symbol('price'))(newValue(20.66));
|
||||||
|
const taxSlot = newSlot(Symbol('tax'))(newValue(4.34));
|
||||||
|
|
||||||
|
console.log(pretty({price: priceSlot}));
|
||||||
|
|
||||||
|
const computeTotal = tax => {
|
||||||
|
const addTax = price => price + tax;
|
||||||
|
return addTax;
|
||||||
|
};
|
||||||
|
|
||||||
|
const total =
|
||||||
|
transform(read(priceSlot))(
|
||||||
|
transform(read(taxSlot))(
|
||||||
|
newValue(computeTotal)));
|
||||||
|
|
||||||
|
console.log(pretty({total}))
|
||||||
|
|
||||||
|
const totalPlusOne = transform(total)(newValue(inc));
|
||||||
|
|
||||||
|
console.log(pretty({totalPlusOne}));
|
||||||
|
|
||||||
|
verifyComputation(totalPlusOne);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// const price = newSlot(Symbol('price'))(newValue(20.66));
|
console.log("getReadDependencies(totalPlusOne):", getReadDependencies(totalPlusOne));
|
||||||
// const tax = newSlot(Symbol('tax'))(newValue(4.34));
|
|
||||||
|
|
||||||
// console.log(pretty({price}));
|
|
||||||
|
|
||||||
// const total =
|
|
||||||
// transform(read(price))(
|
|
||||||
// transform(read(tax))(
|
|
||||||
// newValue(tax => price => price + tax)));
|
|
||||||
|
|
||||||
// console.log(pretty({total}))
|
|
||||||
|
|
||||||
// const totalPlusOne = transform(total)(newValue(x => x + 1));
|
|
||||||
|
|
||||||
// console.log(pretty({totalPlusOne}));
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// const getReadDependencies = computation => new Set([
|
|
||||||
// ...(computation.kind === "value" ? [] : [computation.in, ...getReadDependencies(computation.fn)]),
|
|
||||||
// ]);
|
|
||||||
|
|
||||||
// console.log("getReadDependencies(total):", getReadDependencies(total));
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue