Comment by bbor
To this noob, this seems like a problem that was pretty convincingly solved by double entry accounting ledgers, but from your post it sounds like this isn’t a replacement-of but rather an addition-to that model. What’s a situation where an imperative approach would be preferable to the traditional declarative approach? My depth of knowledge pretty much starts and ends with the below document, so apologies if this is obvious to experts!
https://beancount.github.io/docs/the_double_entry_counting_m...
E: the problem being “tracking transactions”. Yes?
That's a very good question. So the DSL here operates an agnostic source/dest transaction model, which is akin to the credit/debit model sans the semantic baggage. The goal of this model is indeed to be "tracking transactions" in the abstract sense, having the benefit of not forcing accounting decisions too early on when there is (still yet) none.
For example, if you create a transaction moving money from "@stripe:main" to "@acct:123" and "@acct:234", you're merely representing the fact that you want this money to be moved. Wether the movement is clearing off a liability or generating revenue is another concern that you (in our model) want to take care of in a separate layer, that will also likely involve some intense intentionality and iterations from your accounting team.
In a sense, it's as close to accounting than it is to warehousing money, moving unitary boxes of it from one location to another.
These two models have the same amount of information per entry, so they can actually be converted from one to another, enabling you to also represent some accounting-ish transactions with this DSL, e.g. with a send [USD/2 100] from @ar:invoices:1234 to @sales.