Use ordinary strings for text your program displays or compares. Use registry-tagged templates when values carry path, regular expression, shell, or SQL intent that requires structured representation. These choices serve distinct purposes. A template value is not merely a string with decorative syntax.
Start with observable Unicode text
Save this as strings-templates.tpz:
let title = "Topaz 💎"
let scalarCount = title.scalars().length
let configPath = p"config/topaz.toml"
let query = sql"SELECT name FROM projects WHERE title = {title}"
print("{title}: {scalarCount}")Check and run it:
topaz check strings-templates.tpz
topaz run strings-templates.tpzThe output is:
Topaz 💎: 7title contains seven Unicode scalar values: five letters, one space, and one emoji. The scalars() method returns an Array<string> whose elements are single-scalar strings. This provides the standard method to inspect text positions. Storage bytes do not represent string positions, and Topaz performs no implicit Unicode normalization.
Because configPath uses the p template, it carries path-normalization intent. query uses the sql template, where {title} serves as a parameter boundary instead of direct SQL text insertion. The program omits printing both templates because template values are structured, non-renderable entities rather than ordinary display strings.
Choose the form by the value you need
| Need | Form | Boundary |
|---|---|---|
| Display or compare text | "Hello, {name}" | Interpolation uses the standard value renderer |
| Multiline text | """...""" | Closing-delimiter indentation controls exact stripping |
| A path template | p"config/app.toml" | Carries platform path-normalization intent |
| A regex template | r"^[a-z]+$" | Only the specified reduced-escaping floor is portable |
| Shell command data | sh"tool {argument}" | Construction does not execute a process |
| Parameterized SQL data | sql"WHERE id = {id}" | Interpolation becomes parameter metadata |
The p, r, sh, and sql tags work with ordinary or triple-quoted strings. The tag must directly precede the opening quote without intervening whitespace. With a space, p "file" parses as an identifier followed by a string rather than a call, producing a parse error.
Ordinary and triple-quoted strings support {expression} interpolation and the fixed escape set. When a newline immediately follows a triple-quoted opening delimiter, that initial newline is omitted. The exact spaces-and-tabs prefix preceding the closing delimiter must appear on each nonblank content line before Topaz removes it.
Common correction
Do not use text[0], text.length, or slicing operations to inspect a string. Call text.scalars() and process the result using standard Array operations. This provides scalar access rather than grapheme-cluster segmentation.
Backticks, ${expression}, single-quoted strings, html"...", unrecognized adjacent tags, and user-defined tags are non-canonical. An sh template does not execute commands, and SQL interpolation does not permit direct text insertion into queries. HTML templates, user tag registration, grapheme-cluster APIs, direct string slicing, a fully fixed cross-platform regex dialect, and shell execution semantics fall outside this language surface.
Refer to Lexical Structure & Layout for quoting and newline rules, Runtime Behavior for rendering details, and Forbidden & Deferred Forms for familiar syntax options that are intentionally unavailable.