Summary of dolo-plus implementation
1. Three layers, two maps¶
The idea is to separate what the model is from how we solve it as cleanly and precisely as possible.
- Since Bellman formulated dynamic programming using recursive application of functional operators, the syntax must map to such operators
- The natural candidate paradign is John Backus' formal functional programming system (FFP)
- Named immutable operations act on value functions and disributions
- Makes it concrete to talk about replicability & modularity
Formally there are three layers:
-
Syntactic layer (DDSL / YAML)
- Human‑written model files.
- Lives in a space of function objects \(\mathbb F \subset \mathbb O\): things like
-
Mathematical layer (Bellman world)
- Lives in \(\mathbb{DM}\): Bellman operators and related dynamic‑model operators.
- Here we have objects like \(\mathcal T\), \(\mathcal S_1, \dots, \mathcal S_K\), state spaces, policies, etc.
-
Computational layer (host language implementation)
- Lives in \(\mathbb F^{\text{COMP}}\): AST‑like representations of actual Python/Julia/… code.
- Concrete grids, arrays, solvers, interpolation objects, etc.
The connection between them is via two explicit maps:
- \(\Upsilon\) (“meaning map”): takes a DDSL function object and returns the mathematical operator it denotes (e.g. a Bellman operator built from the declared spaces and transitions).
- \(\rho\) (“representation map”): takes a calibrated DDSL spec and returns a particular executable (e.g. a Python implementation using Gauss‑Hermite + linear interpolation).
Crucially, both maps are local and explicit: they are part of the formalism, not an informal convention.
2. Why this helps modularity and replicability¶
(a) One mathematical model, many implementations¶
Once a DDSL file is fixed and calibrated, \(\Upsilon\) pins down a unique mathematical object (up to the usual equivalences). Different numerical implementations are then just different choices of \(\rho\):
with the same \(\Upsilon\) but different schemes (e.g. different grids, quadrature, optimization methods). This gives:
- A clean statement of what is structural (the economic model) vs what is numerical (solution scheme).
- A natural way to compare solvers: hold \(\Upsilon(f)\) fixed and vary \(\rho\).
(b) Compositional Bellman structure¶
At the mathematical layer, models are built from stage operators:
with each \(\mathcal S_i\) attached to what I call a “perch” (state space + transitions + movers). The DDSL syntax is designed so that this factorization is visible in the source:
perchesdefine stages and their forward/backward movers.methodsandschemataattach numerical schemes to each stage.
Interpretation: a perch is an information set (a filtration step) within a stage—i.e. what is known/observable/conditionable at that point—not an “endpoint of an operator.”
So you can swap, say, the interpolation scheme on the continuation value locally without rewriting the Bellman operator or the rest of the model.
3. Consistency: mapping back from code to math¶
The consistency point is that we don’t just go from syntax to code; we can also reason backwards:
- From a given implementation in \(\mathbb F^{\text{COMP}}\) we can reconstruct (up to equivalence) the underlying DDSL description and hence its \(\Upsilon\)-image in \(\mathbb{DM}\).
- This gives a precise sense in which “this Python notebook really is solving this Bellman equation, with this state space and these constraints”.
Formally, for calibrated models we aim for \(\Upsilon\) and \(\rho\) to be (locally) invertible on their images:
That’s what turns DDSL specs into portable, auditable model objects rather than just “code that seems to work”.
4. What this buys the profession¶
For an applied economist, the payoffs are very concrete:
- Modularity: stages, shocks, and policies are explicit building blocks that can be reused across models and papers.
- Replicability: a DDSL file + calibration is enough to reconstruct both the Bellman problem and at least one working implementation.
- Comparability of methods: we can systematically compare solution schemes as different \(\rho\)’s for the same \(\Upsilon(f)\).
- Separation of concerns: theorists can argue about \(\Upsilon\) (spaces, operators, constraints); numerical people can argue about \(\rho\) (grids, quadrature, solvers), without mixing the two.
In short, the DDSL is meant to be a standardized front end for dynamic programming models: disciplined enough to support proofs and guarantees, but close enough to economists’ usual notation that writing a stage in YAML feels like writing it on the board.
If this seems promising, I’d be very interested in your feedback on how well this aligns with the way you and your coauthors think about stages, operators, and solution methods in practice.