---
tags: [strings, proposal]
---
# String templates with control flow
It's nice to be able to specify embedded content with tagged string templates.
```kotlin=
html"""
<h1>${ title }</h1>
Do the things:
<ul>${ listItems }</ul>
"""
```
This works because the tag, `html` in this case, receives the literal parts and the interpolated parts:
1. Literal part `"<h1>"`
2. Interpolation `title`
3. Literal part `"</h1>\nDo the things:\n\n<ul>"`
4. Interpolation `listItems`
5. Literal part `"</ul>"`
PHP allows embedding flow control in interpolations.
```php=
<h1><?php echo($title) ?></h1>
Do the things:
<ul><?php
foreach ($listItems as $listItem) {
?>
<li><?php
echo($listItem)
?></li><?php
}
?></ul>
```
Some [JS tag libraries](https://lit.dev/docs/v1/lit-html/template-reference/#control-flow-with-javascript) have struggled with flow control.
What would we need to provide a tag with a sequence of literal parts and interpolations using regular Temper control flow?
PHP has two parts:
- transitions from template fragments to PHP code and back
- an `echo` function that emits an interpolated value.
Let's consider some hand-wavy code in the Temper style and how it might desugar to simpler constructs.
```
html"""(out);;
<h1>${ title }$</h1>
Do the things:
<ul>
${
for (let item of items) {
}$ <li>${ out.emit(item) }$</li>${
}
}$
</ul>
"""
```
This differs from our current interpolated strings in a few ways:
1. `(out);;` after the opening quotes, like a block lambda formal parameter list, gives code inside interpolations something to refer to. Like `echo` in PHP.
2. `${` pairs with `}$` instead of with `}` which means `for (let item of items) {` is not ended by the `}` immediately following it.
How could we manipulate this to produce a series of literal text and interpolated values for the `html` tag to process?
This could transform to:
```C=
// Introduce a block to preserve
// apparent scope boundaries.
{
// Capture the tag to preserve
// the order of operations.
let tag#0 = html;
// Create an object to collect parts.
let collector#1 = new TagPartsCollector();
// based on (out);;
// Let user code add interpolations
// but not literal sections.
let out = collector#1.interpolations;
collector#1.literal("<h1>");
// Maybe some convention can let
// us recognize and auto-emit
// "simple" interpolations.
out.emit(title);
collector#1.literal("""
</h1>
Do the things:
<ul>
""");
// Here, the tokens for
for (let item of items) {
collector#1.literal("\n <li>");
out.emit(item);
collector#1.literal("</li>");
}
collector#1.literal("\n</ul>");
// Finally, invoke the tag
tag#0(collector#1.build())
}
```
So allowing tagged templates with embedded flow controls requires:
- a way to define a name to which code can send interpolated values, `out` in this example. This could be defaulted à la Kotlin `it`
- a way to identify when an interpolation ends independent of flow control constructs block endings
and benefits from
- a way to identify which interpolations are "simple", which should be implicitly emitted.
One rule of thumb could be, if there is no statement level token (`{`, `}`, `;`) outside non-statement-level brackets, nor a reference to the output channel.
but otherwise, the desugaring is fairly straightforward.
----
Problems: if `html` were a macro, it would need to do flow-sensitive analysis if it wanted to, at compile time, pick escapers based on the structure of HTML produced. If `out` were passed into other functions that might be impossible.
Specifically providing for branching and looping operations might simplify things.
## Generic tag-based control flow
Suppose we have generic structure based on tags that map to blocks:
```
let q =
Bob"""
Text.
$<for let a of x>$
Repeated line: $a
$</for>$
"""
```
This might desugar to:
```
let q = Bob() { bob;;
bob.emit("Text.");
bob.for(let a of x) { bob2;;
bob2.emit("Repeated line: ");
bob2.arg(a);
}
}
```
Pros and cons:
* Con: you have to recreate all the Temper control flow structures.
* Pro: more direct control allows static analysis and optimization.
* Pro/con: won't have the flexibility of a full language