From 614e6c0fdbd548d15602940668178f4a60b0487b Mon Sep 17 00:00:00 2001 From: Joeri Exelmans Date: Wed, 16 Apr 2025 16:32:06 +0200 Subject: [PATCH] read-dependencies now correctly recorded (i think) --- scripts/versioning2.js | 133 +++++++++++++++++++++++++---------------- 1 file changed, 82 insertions(+), 51 deletions(-) diff --git a/scripts/versioning2.js b/scripts/versioning2.js index a825f76..2d21502 100644 --- a/scripts/versioning2.js +++ b/scripts/versioning2.js @@ -1,99 +1,130 @@ import { pretty } from "../util/pretty.js"; -import { inspect } from "node:util"; +import { deepEqual } from "../util/util.js"; // UUID -> Computation -> Slot const newSlot = uuid => computation => ({ overwrites: uuid, computation, // depth: 1, - // [inspect.custom]: (depth, options, inspect) => options.stylize(`newSlot(${inspect(uuid)})(${inspect(computation)})`, 'special'), }); // a -> Computation const newValue = val => ({ kind: "value", out: val, - // [inspect.custom]: (depth, options, inspect) => options.stylize(`newValue(${val})`, 'special'), }); -const id = x => x; - // Slot -> Computation const read = slot => ({ - kind: "transformation", - in: slot, - fn: { - kind: "value", - out: id, - }, + kind: "read", + slot, out: slot.computation.out, - // [inspect.custom]: (depth, options, inspect) => options.stylize(`read(${inspect(slot)})`, 'special'), }); // Computation -> Computation b> -> Computation const transform = input => fn => { - // console.log("transform...", "input:", pretty(input), "fn:", pretty(fn)); const output = fn.out(input.out); if (input.kind === "value") { - // our input had no read dependency, thus likewise our output does not: + // optimization: sandwich everything together return { kind: "value", out: output, }; } else { - // console.log("transforming the transformation..."); return { kind: "transformation", - in: input.in, - // transform the transformation: - fn: transform(input.fn)(newValue(origFn => { - const descr = `${fn.out.name} ∘ ${origFn.name}`; - return { [descr]: x => fn.out(origFn(x)) }[descr]; - })), + in: input, + fn, 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"); + + verifyComputation(computation.in, indent+1); + verifyComputation(computation.fn, indent+1); + } +} -const valueOne = read(counterOne); +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 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)); -// 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)); +console.log("getReadDependencies(totalPlusOne):", getReadDependencies(totalPlusOne));