Pyro Gets String Interpolation

28th February 2023

I've added support for string interpolation to Pyro, my hobby programming language. This is a feature I've wanted from the very first day I started working on the language.

String interpolation lets you inject the stringified value of an expression into a double-quoted string literal using a ${} block.

Here's a simple example:

var value = "xyz";
assert "abc ${value} def" == "abc xyz def";

The simplest and most common use case for string interpolation is for directly injecting the value of a variable into a string, as above. But a ${} block can contain any valid Pyro expression, so it supports more complicated use cases like manipulating the value of the variable directly inside the interpolation, e.g.

var value = "xyz";
assert "abc ${value:to_upper()} def" == "abc XYZ def";

Pyro's support for interpolated expressions is fully general and recursive — a string can contain an interpolated expression which contains a string which contains an interpolated expression which contains a string which contains an interpolated expression... There's no hard limit to how deep the recursion can go.

I'm quite proud of this feature as parsing fully recursive interpolated expressions is a surprisingly tricky task. It's one of those problems where, the more you think about it, the harder it gets.

I considered adding support for interpolated expressions many times and postponed it many-times-minus-one as being "too much work to do properly".

Then in classic programming style, after low-key thinking about it for two years, the solution popped fully-formed into my head one day as I was taking a shower. I sat down and coded it up in an hour. Like all the best solutions to hard problems, it involved a tiny amount of code relative to the power of the feature.

(I won't try to describe the solution here — anyone who's interested can check the source code for themselves.)

I've had more fun writing code for Pyro than for any other programming project I've worked on, but so far, this has been the most satisfying feature to implement :)