Bicycle is an open-source framework that I’ve been working on with a couple of friends. One way to think about it is to compare it to a spreadsheet.
In a spreadsheet, we are building a directed, acyclical graph of cells, where cells are nodes and each formula in the cell defines the edges and direction.
A1=B1+C1, then both B1 and C1 point to A1. The graph cannot contain cycles, so, in a spreadsheet, you can’t then say that
B1=A1-C1 even though that is true, because it would cause a cycle in the graph.
Bicycle defines a data-structure and algorithm that gives meaning to a graph of formulas that does contain cycles where dependencies between nodes can be bidirectional (hence, Bicycle).
In Bicycle, you can define both of the formulas above and also complete the network with
A1=C1-B1. In more complex networks, an individual field may have several different formulas, using different dependencies that can set its value.
Once you define a network, you can seed it with values. These are kept outside of the formula data-structure in a kind of priority queue. The highest priority values are seeded first, and each value is only accepted into the network if the network can remain consistent.
Meaning, I could define A1 as 2, B1 as 3, but if I then say C1 is 7, I have created an inconsistency. When you attach this to a UI, you would want the oldest value to be discarded.
We are also providing some help building SwiftUI based UIs with it. The network is meant to be hosted in an
@ObservableObject and we provide a
TextField Initializer that will bind to fields in it. Here’s a demo of a network that can convert between yards, feet, and inches.
Try to imagine replicating that in Excel. You’d have to pick one of the fields to be user-provided and put formulas in the other two. In Bicycle, you can provide as many formulas as you want (as long as they are consistent with each other) and seed-values are used as long as they are consistent.
It’s in very early stages and the API will probably change a lot, but if you want to take a look, see SwiftBicycle in GitHub.