The Sneaky String Concatenation Of Jsonnet
When missing plus signs don't break your code—but probably should
Have you ever been bitten by a weird language quirk? Well, I stumbled upon something interesting while working with Jsonnet (that config language that makes our lives easier... mostly).
At first glance, this looks like it should throw an error, right?
This code actually works, despite the lack of a plus operator on the line where a string precedes an object:
It is happening because Jsonnet is automatically converting objects to strings and implicitly concatenating them 🤯
This seems an undesirable effect, but it might not be that unexpected. Let's dig in!
Jsonnet also uses the plus operator for merging objects, e.g.:
And the output will be:
Looking at go-jsonnet parser, it returns a new ast.ApplyBrace value when it finds a left brace token:
It holds the left and right-hand side values. Let's see the ast type definition:
Huh!? Turns out, it's not an unexpected behavior.
It's a syntax sugar, where we can omit the plus operator:
The output will be the same. It's a very common pattern used in Jsonnet. It might not look like so with the contrived example I presented above, but it's normal to see examples such as:
That outputs:
The thing is if either the left or right-hand side of ast.ApplyBrace is a string, the plus operator will be applied and when you try to add anything to a string, the value will be cast to string automatically to be concatenated.
As far as I know, this behavior is not documented but is part of the language spec. I assume this is on purpose, as I doubt anyone would like users trying to rely on such a tricky aspect of the language.
So next time you're concatenating strings in Jsonnet, double-check those plus signs—or your objects might just string themselves along! 😅