Pipeline Operator
Chain function calls in a readable, left-to-right manner with the pipeline operator.
Basic Usage
|>
Pipeline Operator
Passes the left-hand value as the first argument to the right-hand function.
def double(x: Int) -> Int { x * 2 }
def add_one(x: Int) -> Int { x + 1 }
def square(x: Int) -> Int { x * x }
# Without pipeline (nested calls)
result1 = square(add_one(double(5))) # Hard to read
# With pipeline (left to right)
result2 = 5 |> double() |> add_one() |> square()
print(result2) # ((5 * 2) + 1)^2 = 121
With Multiple Arguments
When the right-hand function takes more arguments, the piped value is inserted as the first argument.
def add(a: Int, b: Int) -> Int { a + b }
def multiply(a: Int, b: Int) -> Int { a * b }
# `5 |> add(3)` is shorthand for `add(5, 3)`
result = 5 |> add(3) |> multiply(2) # (5 + 3) * 2 = 16
print(result)
# Inline lambdas via the immediately-invoked `|x| { ... }()` form
def subtract(a: Int, b: Int) -> Int { a - b }
def divide(a: Int, b: Int) -> Int { int(a / b) }
calc = 100
|> |x| { subtract(x, 10) }()
|> |x| { divide(x, 3) }()
|> |x| { multiply(x, 4) }()
print(calc) # ((100 - 10) / 3) * 4 = 120
With Collection Methods
Iteration over arrays uses method chaining: .map, .filter, .reduce, .each. Lambdas are most concise in pipe form — |x| x + 1 — but fn(x) x + 1 works too.
numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
# Method chaining with pipe lambdas
evens_squared = numbers
.filter(|x| x % 2 == 0)
.map(|x| x * x)
print(evens_squared) # [4, 16, 36, 64, 100]
# Reduce with two parameters
sum_of_evens = numbers
.filter(|x| x % 2 == 0)
.reduce(|acc, x| acc + x, 0)
print(sum_of_evens) # 30
# `.each` for side effects
numbers.filter(|x| x > 5).each(|x| print(x))
You can still use |> with these chains by pre-defining a callable, e.g. numbers |> |arr| arr.filter(|x| x > 5)().
Real-World Examples
Data & HTTP processing
# Data processing pipeline
def process_user_data(raw_data: Hash) -> Hash
raw_data
|> |d| { d["sanitized_email"] = d["email"].lower().trim(); d }()
|> validate_user()
|> enrich_profile()
|> calculate_metrics()
end
# HTTP request pipeline
def fetch_and_process(url: String) -> Hash
url
|> HTTP.get_json()
|> transform_response()
|> validate_data()
|> format_output()
end
Complex data pipeline
sales_data = [
{"product": "A", "quantity": 10, "price": 100},
{"product": "B", "quantity": 5, "price": 200},
{"product": "C", "quantity": 15, "price": 50},
]
total_revenue = sales_data
.map(|sale| sale["quantity"] * sale["price"])
.reduce(|acc, rev| acc + rev, 0)
print("Total Revenue: $" + str(total_revenue)) # $2750
Benefits of Pipeline
Readability
Data flows left-to-right, matching natural reading order.
Debugging
Easy to add intermediate steps or breakpoints.
Composability
Build complex transformations from simple functions.
No Nesting
Avoid deeply nested function calls.