Skip to main content

Strings and Interpolation

Zynx provides string interpolation directly in string literals, along with a small, composable formatting syntax. This section explains how to write string literals, interpolate expressions, and control basic formatting.


String Literals

Basic string literals are enclosed in double quotes:

let s = "Hello, world!";

Strings are UTF‑8 and support standard escape sequences (such as \n for newline).


String Interpolation

You can embed expressions directly into strings using {} placeholders. The expression inside {} is evaluated and converted to text.

let name = "Alice";
let age = 30;
let message = "Name: {name}, Age: {age}";
// message is "Name: Alice, Age: 30"

Any valid expression can be used inside the braces:

let a = 1;
let b = 2;
_ = os.write("Result: {a + 2 * b}\n"); // Result: 5

Interpolation is resolved at runtime. Types that implement string conversion (for example, primitives and many standard types) can be formatted directly; custom types can participate by providing suitable conversion or formatting APIs.


Basic Formatting

A placeholder can include an optional format specifier after a colon:

{expression[:[[fill]align][0][width][.precision]]}

All components after the colon are optional. If no format specifier is given, a default representation is used for the expression type.

Alignment and Fill

Alignment controls where the formatted value appears within the output field:

  • < - Left‑aligned (default for strings and booleans).
  • > - Right‑aligned (default for numbers).
  • ^ - Center‑aligned.

You can specify a fill character immediately before the alignment character:

let x = "Zynx";
_ = os.write("[{x:<8}]\n"); // [Zynx ] (left, default fill space)
_ = os.write("[{x:>8}]\n"); // [ Zynx] (right)
_ = os.write("[{x:^8}]\n"); // [ Zynx ] (center)
_ = os.write("[{x:*^8}]\n"); // [**Zynx**] (center, fill with '*')

Width

The width is a decimal integer specifying the minimum number of characters for the resulting field. If the value is shorter, it is padded according to the alignment rules.

let n = 42;
_ = os.write("|{n:5}|\n"); // | 42|
_ = os.write("|{n:<5}|\n"); // |42 |

Zero Padding

For numeric types, you can use 0 before the width to pad with zeros. This is shorthand for right‑alignment with '0' as the fill character.

let n = 42;
_ = os.write("{n:05}\n"); // 00042
_ = os.write("{n:0>5}\n"); // 00042 (equivalent)

Precision

Precision is introduced with a . followed by an integer:

  • For floating‑point values, precision controls the number of digits after the decimal point.
  • For strings and booleans, precision limits the maximum number of characters (truncation).
let pi = 3.14159;
let name = "ZynxLanguage";

_ = os.write("{pi:.2}\n"); // 3.14
_ = os.write("{pi:8.2}\n"); // " 3.14" (width 8, right-aligned)
_ = os.write("{name:.4}\n"); // Zynx

Width and precision can be combined with alignment and fill in the usual way.


Special Characters and Escaping

To include literal curly braces in an interpolated string, escape them by doubling:

_ = os.write("Literal braces: {{ }}\n");
// Output: Literal braces: { }

Other special characters (such as newlines or quotes) use standard escape sequences:

let s = "Line 1\nLine 2";
let quote = "He said, \"Zynx\".";

Usage and Lifetime Considerations

Interpolated strings are constructed efficiently:

  • The implementation computes the required length from the literal segments and formatted components.
  • A temporary buffer is allocated (typically on the stack or in a short‑lived workspace).
  • Literal parts and formatted values are written into this buffer in sequence.

This design works well for:

  • Logging and diagnostics,
  • Producing messages for I/O (os.write, logging APIs),
  • Passing formatted strings to short‑lived consumers.

See also

  • Type System - core str type and related primitives.
  • Control Flow - examples where formatted strings appear in branches and loops.
  • Error Handling - formatting error values in messages.