← All Examples FP

Pipes & Composition

JAPL's pipe-forward operator |> lets data flow left-to-right through function chains. Combined with higher-order functions, this enables expressive, readable data transformations.

Source Code: Pipes

fn double(x: Int) -> Int { x * 2 }
fn add(x: Int, y: Int) -> Int { x + y }
fn to_str(x: Int) -> String { show(x) }

fn main() {
  let result = 5 |> double |> double
  println(show(result))

  let msg = 42 |> to_str
  println(msg)
}

Source Code: Higher-Order Functions

fn apply(f: fn(Int) -> Int, x: Int) -> Int { f(x) }
fn double(x: Int) -> Int { x * 2 }
fn square(x: Int) -> Int { x * x }

fn apply_twice(f: fn(Int) -> Int, x: Int) -> Int { f(f(x)) }

fn main() {
  println(show(apply(double, 5)))
  println(show(apply(square, 4)))
  println(show(apply_twice(double, 3)))
  let add_ten = fn(x: Int) { x + 10 }
  println(show(apply(add_ten, 5)))
}

What This Demonstrates

Line-by-Line Breakdown

let result = 5 |> double |> double
Starts with 5, pipes it into double (getting 10), then pipes that into double again (getting 20). Reads left-to-right, like a Unix pipeline.
fn apply(f: fn(Int) -> Int, x: Int) -> Int
Takes a function f and a value x, and applies f to x. The function type is written fn(Int) -> Int.
fn apply_twice(f: fn(Int) -> Int, x: Int) -> Int { f(f(x)) }
Applies f twice. apply_twice(double, 3) computes double(double(3)) = 12.
let add_ten = fn(x: Int) { x + 10 }
An anonymous function bound to a local variable. It can be passed to apply just like a named function.

Try Modifying