Skip to content

compiler: add then/2 and tap/2 support for functional pipelines#119

Merged
yevbar merged 1 commit intomasterfrom
happy/then-tap-support
Mar 1, 2026
Merged

compiler: add then/2 and tap/2 support for functional pipelines#119
yevbar merged 1 commit intomasterfrom
happy/then-tap-support

Conversation

@yevbar
Copy link
Copy Markdown
Contributor

@yevbar yevbar commented Mar 1, 2026

Summary

Add support for Elixir's then/2 and tap/2 functions in the Firebird compiler, enabling idiomatic functional pipeline patterns in WASM-compiled code.

Changes

then/2 — Transform values in pipelines

@wasm true
def transform(x) do
  x
  |> then(fn v -> v + 1 end)
  |> then(fn v -> v * 3 end)
end

Compiles to efficient let-bindings in IR, then optimized WASM locals.

tap/2 — Pass-through in pipelines

@wasm true
def process(x) do
  x
  |> tap(fn _v -> 0 end)  # no-op in pure WASM (no side effects)
  |> then(fn v -> v * 2 end)
end

Since the WASM subset is pure (no side effects), tap/2 compiles to an identity — the function body is dead code. This allows tap/2 calls in pipelines to compile cleanly.

Supported syntax

  • Local: then(value, fn x -> body end), tap(value, fn x -> body end)
  • Remote: Kernel.then(value, fn x -> body end), Kernel.tap(value, fn x -> body end)
  • Pipe: value |> then(fn x -> body end), value |> tap(fn x -> body end)

Tests

14 new tests covering compilation, WASM execution correctness, pipeline chaining, Kernel remote syntax, and optimization pass interaction.

Add support for Elixir's then/2 and tap/2 functions in the compiler,
enabling functional pipeline patterns in WASM-compiled code:

- then/2: apply anonymous function to a value and return the result
  Compiles to a let-binding in IR: value |> then(fn x -> x * 2 end)
  becomes {:block, [{:let, tmp, value_ir}, body_ir]}

- tap/2: apply function for side-effect, return original value
  In the pure WASM subset (no side effects), tap simply returns
  the original value, allowing tap/2 calls in pipelines to compile

Both local call syntax (then/tap) and Kernel remote call syntax
(Kernel.then/Kernel.tap) are supported. Works with pipe operator
for idiomatic Elixir pipeline chains.

Includes 14 tests covering:
- Basic then/2 and tap/2 compilation
- Pipeline chaining (value |> then(...) |> then(...))
- Mixed tap/then pipelines
- Multi-expression function bodies
- Kernel.then/2 and Kernel.tap/2 remote call syntax
- WASM execution correctness
- Optimization pass interaction (constant folding through then)
@yevbar yevbar merged commit aea78c4 into master Mar 1, 2026
3 of 4 checks passed
@yevbar yevbar deleted the happy/then-tap-support branch March 1, 2026 08:39
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant