What String Interpolation Fixes in Rego
OPA is a general-purpose policy engine. Policies in its language, Rego, answer questions like whether a runner can deploy to a given environment or who can edit a specific path in a git repo. Before OPA 1.12, generating a message with a username required calling sprintf with formatting directives and separately handling the case where the username was undefined. String interpolation removes both steps. The policy becomes a single line with the variable embedded directly in the string.
Parser Changes: Two New Tokens
The first change targets the parser, which scans raw source code and breaks it into tokens. The team added two new tokens for string interpolation: one marks any segment inside an interpolated string, and the other marks the end of the interpolated string. From those tokens the parser builds a new AST node called template_string. That node holds the individual parts of the expression, each of which the later stages process separately.
Compiler Step: Rewriting the AST Node
The compiler turns parser output into something executable through a series of steps. Not every AST node survives to execution unchanged. The template_string node does not. The compiler rewrites it into a call to a new built-in function also named template_string. The team also shipped a compiler explorer tool so users can watch exactly how their own policy code gets rewritten before execution.
Interpreter: Evaluating the Built-in
The template_string built-in runs inside topdown, the Rego interpreter. The implementation recurses through each part of the templated string, evaluates it, checks that each part resolves to exactly one value (a requirement for string interpolation), and concatenates all parts into the final string. The single-value requirement is what prevents ambiguous results when a variable in the template is undefined.
The Full Cost of a Language Change
Changing OPA does not end with the OPA repository. Editor grammars, go-to-definition tooling, documentation, and linter rules all needed updates. The linter now flags policies that should use string interpolation and suggests the change automatically. The team considers string interpolation a best practice and updated documentation to reflect that. Egan’s point is direct: every language change carries this full cost, and the team weighed it carefully before committing to the feature.
Notable Quotes
all language changes have a cost Charlie Egan · ▶ 02:02
We want Rego to work well everywhere and that’s a huge part of the work uh when you take on adding a new feature like this as well. Charlie Egan · ▶ 05:15
Key Takeaways
- String interpolation in OPA 1.12 replaces sprintf calls and undefined-handling boilerplate.
- The compiler rewrites the template_string AST node into a built-in function before execution.
- A language change requires updating editor grammars, tooling, docs, and linter rules across the ecosystem.
About the Speaker(s)
Charlie Egan has worked in the cloud-native space since 2018. He works at Apple on OPA and Regal, focusing on authentication and authorization. He is active in the OPA Community Slack.