Data & Control

Pipelines & Placeholders

Trace one value through first-argument insertion, explicit placeholders, callables, and fields.

Use a pipeline when a result should visibly flow into the next operation. left |> right evaluates left once, saves that value, and then chooses one well-defined way to supply it to right. A placeholder _ marks the exact call-argument position that receives the saved value.

Start with a self-contained pipeline

Save this as pipelines-placeholders.tpz:

TOPAZ
function add(value: int, amount: int) -> int {
    value + amount
}

function multiply(left: int, right: int) -> int {
    left * right
}

function equal(left: int, right: int) -> bool {
    left == right
}

let result = 5
    |> add(2)
    |> multiply(_, 3)
let repeated = result |> equal(_, _)

print("{result} {repeated}")

Check and run it:

BASH
topaz check pipelines-placeholders.tpz
topaz run pipelines-placeholders.tpz

The output is:

Output
21 true

The first stage has no placeholder, so the saved 5 is inserted as the first argument: add(5, 2). The second stage says exactly where the saved 7 goes: multiply(7, 3). In the final pipeline, both placeholders receive the same saved 21, so the call is equivalent to equal(21, 21). The left side is not evaluated again for the second placeholder.

Choose the right-hand shape

Right sideMeaning
value |> call(other)Insert value before all explicit positional, spread, and named arguments
value |> call(_, other)Replace every valid _ argument with value; do not also insert it
value |> callableCall the callable with value as its one argument
value |> .fieldRead field from value

Pipelines associate from left to right, so each stage receives the completed value from the stage before it. The placeholder belongs to its nearest containing call. A _ inside a pattern is instead a wildcard that discards a matched value; the two roles share a token but not a scope.

Multiple placeholders are valid when each appears in a call-argument position. They all receive the same saved left value. Placeholder replacement takes priority: once a valid _ exists on the right, Topaz does not insert an extra first argument.

Common correction

A bare _ is not a value. It cannot be the whole pipeline right side, a callee, a member name, or a field label. Put it inside the argument list of the call that should receive the piped value.

Optional-property pipe sugar such as value |> ?.field is not supported. Use ordinary optional chaining before or inside an explicit lambda. Named arguments must still follow positional and spread arguments after pipeline binding. A right side that is neither a call, a callable value, nor .field is a static error.

Pipelines do not add automatic Result propagation, partial application, asynchronous lifting, or a user-defined pipe operator. Use postfix ? explicitly for Result propagation and concurrent explicitly for bounded concurrent work.

See Operators & Expressions for precedence, Functions & Generics for callable values, and Collections & Comprehensions for collection-producing stages.