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.
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 }
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.
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.
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.

Comments
Nothing yet. Say the first thing.
Sign in to join the conversation.