# coalescing

URL: /kida/api/compiler/coalescing/
Section: compiler
Description: F-String Coalescing for Kida Compiler.

RFC: fstring-code-generation

Generates Python f-strings for consecutive template output operations
instead of multiple `buf.append()` calls, reducing function call overhead
by ~37% in output-heavy templates.

Example transformation:
Before (5 function calls):
    _append('<div id="')
    _append(_e(item["id"]))
    _append('">')
    _append(_e(item["name"]))
    _append('</div>')

After (1 function call):
    _append(f'<div id="{_e(item["id"])}">{_e(item["name"])}</div>')

Design:
- Only coalesce consecutive Data and simple Output nodes
- Fall back to separate appends for complex expressions (function calls, etc.)
- Use ast.JoinedStr for f-string generation (handles brace escaping automatically)
- Detect backslashes in expressions (f-strings don't allow them)

Uses inline TYPE_CHECKING declarations for host attributes.
See: plan/rfc-mixin-protocol-typing.md

---

> For a complete page index, fetch /kida/llms.txt.

Open LLM text
(/kida/api/compiler/coalescing/index.txt)

Share with AI

Ask Claude
(https://claude.ai/new?q=Please%20help%20me%20understand%20this%20documentation%3A%20%2Fkida%2Fapi%2Fcompiler%2Fcoalescing%2Findex.txt)

Ask ChatGPT
(https://chatgpt.com/?q=Please%20help%20me%20understand%20this%20documentation%3A%20%2Fkida%2Fapi%2Fcompiler%2Fcoalescing%2Findex.txt)

Ask Gemini
(https://gemini.google.com/app?q=Please%20help%20me%20understand%20this%20documentation%3A%20%2Fkida%2Fapi%2Fcompiler%2Fcoalescing%2Findex.txt)

Ask Copilot
(https://copilot.microsoft.com/?q=Please%20help%20me%20understand%20this%20documentation%3A%20%2Fkida%2Fapi%2Fcompiler%2Fcoalescing%2Findex.txt)

Module

#
`compiler.coalescing`

F-String Coalescing for Kida Compiler.

RFC: fstring-code-generation

Generates Python f-strings for consecutive template output operations
instead of multiple`buf.append()`calls, reducing function call overhead
by ~37% in output-heavy templates.

Example transformation:

Before (5 function calls):
_append('<div id="')
_append(_e(item["id"]))
_append('">')
_append(_e(item["name"]))
_append('
')

After (1 function call):
_append(f'<div id="{_e(item["id"])}">{_e(item["name"])}
')

Design:

- Only coalesce consecutive Data and simple Output nodes

- Fall back to separate appends for complex expressions (function calls, etc.)

- Use ast.JoinedStr for f-string generation (handles brace escaping automatically)

- Detect backslashes in expressions (f-strings don't allow them)

Uses inline TYPE_CHECKING declarations for host attributes.
See: plan/rfc-mixin-protocol-typing.md

1Class

## Classes

`FStringCoalescingMixin`

7

▼

Mixin for f-string coalescing optimization.

Host attributes and cross-mixin dependencies are decla…

Mixin for f-string coalescing optimization.

Host attributes and cross-mixin dependencies are declared via inline
TYPE_CHECKING blocks.

#### Attributes

Name
Type
Description

`_cached_pure_filters`

`frozenset[str] | None`

—

#### Methods

Internal Methods
6

▼

`_get_pure_filters`

0

`frozenset[str]`

▼

Get combined set of built-in and user-defined pure filters.

Cached per Compile…

`def _get_pure_filters(self) -> frozenset[str]`

Get combined set of built-in and user-defined pure filters.

Cached per Compiler instance so the union is computed once per
`compile()`call, not once per Filter/Pipeline node.

##### Returns

`frozenset[str]`

`_is_coalesceable`

1

`bool`

▼

Check if node can be coalesced into an f-string.

Coalesceable nodes:
- Dat…

`def _is_coalesceable(self, node: Node) -> bool`

Check if node can be coalesced into an f-string.

Coalesceable nodes:

- Data nodes (literal text)

- Output nodes with simple expressions

Non-coalesceable nodes:

- Control flow (If, For, While, etc.)

- Output with complex expressions (function calls, etc.)

- Any node containing backslashes in string constants

##### Parameters

Name
Type
Description

`node`
`—`

##### Returns

`bool`

`_is_simple_output`

1

`bool`

▼

Check if Output node is simple enough for f-string.

`def _is_simple_output(self, node: Output) -> bool`

##### Parameters

Name
Type
Description

`node`
`—`

##### Returns

`bool`

`_is_simple_expr`

1

`bool`

▼

Recursively check if expression is simple enough for f-string.

Simple expressi…

`def _is_simple_expr(self, expr: Node) -> bool`

Recursively check if expression is simple enough for f-string.

Simple expressions:

- Constants (strings, numbers, booleans) without backslashes

- Names (variable references)

- Attribute access (name.attr, name.attr.subattr)

- Item access (name[key], name["key"])

- Pure filters with simple arguments

- Pipelines with all pure steps

- InlinedFilter (method calls like .upper())

Complex expressions (NOT coalesceable):

- Function calls (may have side effects)

- Ternary expressions (complex control flow)

- Binary/unary ops (complex evaluation)

- Expressions containing backslashes in string constants

Backslash detection is integrated into this single-pass traversal
rather than using a separate _expr_contains_backslash() walk.

##### Parameters

Name
Type
Description

`expr`
`—`

##### Returns

`bool`

`_compile_coalesced_output`

1

`ast.stmt`

▼

Generate f-string append for coalesced nodes.

Note on brace handling:
ast.…

`def _compile_coalesced_output(self, nodes: list[Any]) -> ast.stmt`

Generate f-string append for coalesced nodes.

Note on brace handling:

```
ast.JoinedStr automatically handles brace escaping when the AST
is compiled to bytecode. We do NOT manually escape {{ and }}.
Literal text goes into ast.Constant nodes as-is.
Expressions go into ast.FormattedValue nodes.
```

Note on backslashes:

```
F-strings cannot contain backslashes in expression parts.
We detect backslashes during coalesceable checking and fall back.
```

##### Parameters

Name
Type
Description

`nodes`
`—`

##### Returns

`ast.stmt`

`_compile_body_with_coalescing`

1

`list[ast.stmt]`

▼

Compile template body with f-string output coalescing.

Groups consecutive coal…

`def _compile_body_with_coalescing(self, nodes: list[Any]) -> list[ast.stmt]`

Compile template body with f-string output coalescing.

Groups consecutive coalesceable nodes and generates single f-string
appends for groups of 2+ nodes. Falls back to normal compilation
for single nodes or non-coalesceable nodes.

##### Parameters

Name
Type
Description

`nodes`
`—`

List of template AST nodes to compile

##### Returns

`list[ast.stmt]`

List of Python AST statements
