Several years ago, I worked through my US IRS tax return forms by coding the data and calculations in Scheme. The representation ended up being that each form line value was a Scheme procedure that called other such procedures, which was one way to enforce dependencies. (Fortunately, there were no cycles in the dependencies, like the article author found in their CRA payroll deductions work.)
I don't have the code handy, but the procedures typically looked like this:
It was a lot of work, but (since I used error placeholders for many code paths my own data wouldn't exercise) not that much more work than I had to do anyway, for doing my returns with just the PDF forms and instructions. (The extra work came when I had to enter and double-check the form data manually in the official format, for this one-off exercise.)
I did this exercise to see what it would look like, would it save me time/headache, and did it suggest anything about DSLs for this kind of work (say, for domain experts to codify and maintain something more formal and checkable than the form instructions or tax code).
I used to do the same with just Excel. First sheet called 1040, one row per line. Schedules and worksheets got additional sheets, so I could easily pull in the values from and to other sheets.
In this case, I was first seeing what could be done with basic Scheme algorithmic programming language mechanisms (e.g., using procedures and the magic of toplevel definitions).
Then, after seeing how tax form logic ended up that way, one direction would be to define a DSL that makes that easier to work with. For example, if we find everything can be implemented as these procedures, or with maybe with an additional concept (such as to handle cycles like in the article), a simple first step DSL might be another s-expression language that has magic variables that are more akin to spreadsheet cell references, in that the dependencies are evaluated in order. And it might also do things like populate a hashtable with the cached values for application use (e.g., PDF form-filling). That DSL might be implemented as a simple `syntax-case` or `syntax-parse` transformer. If that works and could, we could optimally make it more palatable/marketable/politic by defining a keywords-and-whitespace grammar that parses by transforming those syntax objects to syntax objects in our intermediate s-expression DSL (which transforms to the basic Scheme code approach we worked out originally).
I don't have the code handy, but the procedures typically looked like this:
It was a lot of work, but (since I used error placeholders for many code paths my own data wouldn't exercise) not that much more work than I had to do anyway, for doing my returns with just the PDF forms and instructions. (The extra work came when I had to enter and double-check the form data manually in the official format, for this one-off exercise.)I did this exercise to see what it would look like, would it save me time/headache, and did it suggest anything about DSLs for this kind of work (say, for domain experts to codify and maintain something more formal and checkable than the form instructions or tax code).