Skip to main content
株式会社オブライト
Software Development2026-09-207 min read

Bend 2: GPU, Dependent Types and Proofs in One Language

Bend 2 unifies dependent types, checked proofs, affine ownership, and GPU execution in one Apache 2.0 language, with install steps, code, and Rust comparison.


Bend 2 is a functional programming language that lets you write specifications as dependent types and machine-checked proofs via a law statement paired with a matching def implementation. It uses affine ownership by default, automatically parallelizes work through the a b = f(x) g(y) syntax, and switches a function call to GPU execution on Metal or CUDA simply by marking it with ! when the --gpu flag is on. Released around September 18, 2026, it hit 603 points on Hacker News, drawing attention for combining dependent types, formal proofs, and GPU parallelism in a single language.

This article is a snapshot based on the official site (bend2.dev) and its explainer note, "What is Bend2?", as published. The current version is 2.0.5, licensed under Apache 2.0, with the compiler, standard library, and native backends all open source. As an actively developed OSS project, details may change, so check the official docs for the latest behavior.

Bend 2 execution model: main.bend passes through type checking and law proof checking in the Bend compiler, then splits into running via Bun and producing a native binary, leading to BendRT native execution, a JavaScript backend, and GPU execution on Metal or CUDA

Feature: dependent types and law-based proofs

Bend 2's headline feature is writing the specification itself as a dependent type. It also has a dedicated law construct: you declare a property, then write a matching def implementation, and the compiler mechanically checks the proof. The official docs give this example, proving that canceling an order twice is the same as canceling it once (idempotence).

law cancel_idempotent:
  for order: Order
  {cancel(cancel(order)) == cancel(order) : Order}

def cancel_idempotent(order):
  match order:
    case Pending{}: {==}
    case Cancelled{}: {==}
    case Shipped{}: {==}

The law block states the property, and the def is its proof body: it pattern-matches with match and shows equality with the {==} construct, so the compiler checks every case and accepts it as a proof. Rather than confirming behavior worked by chance via tests, Bend 2 puts the property itself under type checking — that's the core of its dependent-types-plus-law mechanism.

Feature: affine ownership

By default, Bend 2 treats every value as usable at most once — affine ownership. Reusing a value requires explicitly opting in with a + binder (as seen in +d: Nat in the pow2 example below). This constraint lets the language perform in-place updates and predictable memory reclamation without relying on a tracing garbage collector.

Feature: automatic parallelism and GPU execution

Bend 2 doesn't require calling explicit thread-pool or async/await APIs. Binding two expressions with a b = f(x) g(y) lets BendRT — a fork/join-style compiled runtime that replaced Bend 1's HVM interaction-net evaluator — automatically parallelize the work where possible.

Further, marking a call with ! while --gpu is enabled (e.g. f!(x)) runs that call on the GPU. Supported backends are Metal and CUDA, and there's no need to write a separate kernel — the same function definition can be sent straight to the GPU, which is the key difference from CUDA. Note that the JavaScript backend only runs sequentially.

What it's for: use cases

- Implementing algorithms or data structures where you want a property (such as a state transition being idempotent) expressed as a type and mechanically checked by the compiler
- Prototyping numerical or batch workloads where you want parallel and GPU execution from the same function definitions, without writing separate CUDA kernels
- Processes where you want automatic parallelism from the a b = f(x) g(y) syntax alone, without hand-managing threads or async code
- Systems where you want predictable ownership and memory management in a way distinct from borrow-checker languages like Rust
- Learning formal methods with a simpler syntax than a tactic language like Lean 4, while still getting hands-on with the idea of machine-checked proofs

Install and run

Bend 2 runs via Bun and can also be compiled to a native binary. Full source-install steps are in the official note (bend2.dev/notes/install-bend2-from-source); the rough flow looks like this.

# Runs via Bun, not npm
curl -fsSL https://bun.sh/install | bash
git clone https://github.com/HigherOrderCO/Bend2
cd Bend2
bun install

Once installed, the bend command type-checks and runs a file. Compiling to a native binary lets you pass --threads to control thread count, and bend guide opens the bundled documentation on the spot.

# Type-check and run
bend main.bend

# Compile to a native binary
bend main.bend -o main
./main --threads 4

# Browse the bundled docs
bend guide

Minimal usage: a code example

The official docs' hello-world-equivalent example computes a power of two with a function called pow2. Notice that the affine-ownership binder +d: Nat and the automatic-parallelism syntax a b = pow2(p) pow2(p) both show up in this same short snippet.

import Base

def main() -> U32:
  pow2(12n)

def pow2(+d: Nat) -> U32:
  match d:
    case 0n:
      1
    case 1n+p:
      a b = pow2(p) pow2(p)
      (a + b : U32)

import Base loads the standard library, and def main() -> U32 is the entry point. Pattern-matching on the natural number Nat with match, branching on the 0n case and the 1n+p case (one plus a predecessor p), is a typical example of Bend 2's typed pattern matching.

How it compares to existing tools and languages

Bend 2's originality lies in unifying dependent types, proofs, and parallel/GPU execution in one language, but several tools and languages are close on individual axes. Here's how it compares to five of them.

Compared toDifference from Bend 2
Bend 1The runtime moved from Bend 1's HVM interaction-net evaluator to BendRT, a fork/join-style compiled runtime, and the syntax is fundamentally different. Law-based proofs and dependent types are new in Bend 2
RustRust relies on a borrow checker for static ownership checking, while Bend 2 emphasizes affine ownership plus machine-checked law proofs. Parallelism is automatic rather than explicit thread management, using fixed task assignment rather than work-stealing
Lean 4Lean 4 offers rich proof support such as tactics and proof search; Bend 2 lacks tactics or proof search, so proof terms must be written explicitly. In exchange, proof checking is fast, and parallelism and GPU execution are built into the language
CUDACUDA requires writing a separate kernel for parallel work, while Bend 2 switches the same function definition to GPU execution just by marking it with !. It trades direct control for simplicity
FutharkFuthark is also a data-parallel functional language targeting GPU execution, but Bend 2 differs by also layering formal verification — dependent types and law-based proofs — on top of parallelism and GPU support

Current limitations (maturity)

Bend 2 is a young, actively developed project. As of the official docs, the following are not yet available, and are worth knowing before adopting it.

- No tactics or proof search — every proof term must be written explicitly (unlike Lean 4's automated proof assistance)
- No incremental compilation — every change requires a full rebuild
- No debugger
- No language server (LSP), so editor completion and diagnostics support is limited
- Documentation is organized in three layers — basics (hello world, functions, pattern matching, lists), performance (sharing/duplication control, arrays, automatic parallelism, GPU execution), and formal verification (dependent types, equality, proof by induction) — and is still evolving

What is Bend 2?

It's a functional programming language where specifications are written as dependent types and properties are expressed as machine-checked proofs via a law statement paired with a matching def. It uses affine ownership by default and supports automatic parallelism plus GPU execution on Metal/CUDA backends. It hit 603 points on Hacker News shortly after its release around September 18, 2026.

How does it differ from Bend 1?

Bend 2 replaces Bend 1's HVM interaction-net evaluator with BendRT, a fork/join-style compiled runtime. The syntax is fundamentally different, and law-based proofs and dependent types are new additions introduced in Bend 2.

How do you run code on the GPU?

With the --gpu flag enabled, mark the function call you want on the GPU with ! (e.g. f!(x)). Supported backends are Metal and CUDA, and no separate kernel needs to be written. The JavaScript backend only runs sequentially.

How is it different from Rust or Lean 4?

Rust emphasizes static ownership checking via a borrow checker, while Bend 2 emphasizes affine ownership plus machine-checked law proofs. Compared to Lean 4, Bend 2 lacks tactics or proof search, so proof terms must be written explicitly, but proof checking is fast and parallelism plus GPU execution are built into the language.

How do you install it?

Run it via Bun, or compile it to a native binary. Source-install steps are documented in the official note (bend2.dev/notes/install-bend2-from-source). Use bend main.bend to type-check and run, bend main.bend -o main to produce a native binary, and bend guide to browse the bundled documentation.

What are its current limitations?

As of the official docs, Bend 2 lacks tactics or proof search, incremental compilation, a debugger, and a language server (LSP). It's an actively developed project, so it's worth checking the official docs for the latest status before adopting it.

Related free tools (no sign-up, instant results)

Feel free to contact us

Contact Us