Use a pipeline when a result should visibly flow into the next operation.
left |> right evaluates left once, saves that value, and determines a single
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:
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:
topaz check pipelines-placeholders.tpz
topaz run pipelines-placeholders.tpzThe output is:
21 trueThe first stage has no placeholder, inserting the saved 5 as the first
argument: add(5, 2). The second stage explicitly specifies where the saved 7 goes:
multiply(7, 3). In the final pipeline, both placeholders receive the same
saved 21, making the call equivalent to equal(21, 21). The left side is not
evaluated again for the second placeholder.
Choose the right-hand shape
| Right side | Meaning |
|---|---|
value |> call(other) | Insert value before all explicit positional, spread, and named arguments |
value |> call(_, other) | Replace every valid _ argument with value without inserting an extra first argument |
value |> callable | Call the callable with value as its single argument |
value |> .field | Read field from value |
Pipelines associate from left to right, passing the evaluated value of each stage to the next. The placeholder belongs to its nearest enclosing call. A _ inside a pattern is instead a wildcard that discards a matched value. The two roles share a token but operate in separate scopes.
Multiple placeholders are valid when each appears in a call-argument position. They all receive the same saved left value. Explicit 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 entire pipeline right side, a callee, a member name, or a field label. Place 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 for bounded concurrent work.
See Operators & Expressions for precedence, Functions & Generics for callable values, and Collections & Comprehensions for collection-producing stages.