Calculations
The Challenge
So we have a model.
How do we mutate it so that:
- we can do client-side or server-side
- we can estimate the compute cost ahead of time so
- we can tell/warn the user;
- we can charge;
- we can track progress on long-running operations;
- we can parallelize as much as possible;
- ultimately support probabilities;
- we have undo/redo;
- we can test
Mechanisms
Compute Cost
- all calculation primitives are
fn() -> [cost, Future]
cost
is an integer estimation of cost of calculationFuture
some programming primitive that holds the future async solution to the calculation
- cost will be based on:
- per row: how many values will change and a ‘complexity factor’ for the calculation
- per calc: how many dependent rows there are
- this will require metadata per row (dependencies ..?)
Parallelize
- easy enough for different scenarios (aka different ‘sheets’ in model)
- should be easy enough for goal seeking too (as many different scenarios)
- but what about within a scenario?
- would need to know a dependency tree and therefore when to serialize/parallelize
Undo/Redo
- could do with new scenario per calculation, but:
- confused with ‘real’ user-visible scenarios (… possibly different dimension…?)
- massive memory and copy overhead ..?
- or simpy recalculate with on every undo/redo based on an invert function
- slower but more efficient
- less options for allowing users to jump along history
Probabilities
TBD!
Language Choice
Javascript
Pro’s
- known
- common front-end and back-end
Con’s
- slow
- single threaded (but Workers ..?)
- no choice on numerical type
Rust
Pro’s
- fast
- convert to Web Assembly for front-end
- choice of numerical types
Con’s
- new
- different paradigm for building formula
Both
- different numerical types so models unlikely to match
- hence have to use Rust for all user-visible calculations
- hence why?
- to validate models against each other