Tsonnet #33 - The arithmetic tutorial must go on
Tsonnet gains object merging via the + operator and proper division-by-zero errors, completing (almost) the Jsonnet arithmetic tutorial.
Welcome to the Tsonnet series!
If you’re not following along, check out how it all started in the first post of the series.
In the previous post, we added a full set of binary operators:
We were almost done with the arithmetic tutorial. Two pieces were still missing: object merging, and division by zero error handling. Let’s wrap those up.
Merging objects
The + operator is overloaded to act as an operator to merge two objects.
This sample file:
// samples/objects/merge.jsonnet
{ a: 1, b: 2 } + { b: 3, c: 4 }Results in:
{ "a": 1, "b": 3, "c": 4 }The right-hand side overrides the left-hand side fields.
The cram test looks like this:
I’m adding a helper function in the Ast module to merge two lists of fields:
The type checker only needs to include the overloaded operation:
The interpreter implements the new interpret_object_merge_op function to deal with that, and we pattern-match in the interpret_bin_op function to add it:
Done!
dune exec -- tsonnet samples/objects/merge.jsonnet
{ "a": 1, "b": 3, "c": 4 }
Division by zero
Next we should deal with the division by zero error.
Here’s how Jsonnet handles it:
$ jsonnet samples/errors/divide_by_zero.jsonnet
RUNTIME ERROR: Division by zero.
samples/errors/divide_by_zero.jsonnet:1:1-6 $
During evaluation
And here are the sample files and how I want it to look in Tsonnet:
Not a huge difference from the reference implementation, but I like seeing the faulty operation highlighted in the source — much easier to spot and fix.
Let’s add the error message:
The interpret_arith_op function only needs to pattern-match on Int and Float zero before the division — pretty simple. Have I mentioned how much I enjoy pattern matching?
The guard clauses (when n = Int 0 || n = Float 0.0) catch both integer and float zero before the division cases get a chance to run.
Completing the tutorial
With those two additions in place, samples/tutorials/arith.jsonnet is now fully supported -- minus the string formatting bits I’m deliberately setting aside for later. Here’s the file with those commented out:
Running it:
dune exec -- tsonnet samples/tutorials/arith.jsonnet
{
"concat_array": [ 1, 2, 3, 4 ],
"concat_string": "1234",
"equality1": false,
"equality2": true,
"ex1": 1.6666666666666665,
"ex2": 3,
"ex3": 1.6666666666666665,
"ex4": true,
"obj": { "a": 1, "b": 3, "c": 4 },
"obj_member": true
}String formatting is next on the list -- but there are more interesting features to tackle first, so I’m parking it for now.
Conclusion
Two small additions -- object merging and division by zero -- and the arithmetic tutorial is effectively done. The pattern-matching guard clauses made the zero-division check almost embarrassingly straightforward, and the merge_fields helper slotted in without touching anything else.
You can check the entire diff here.








