What is Bend? Formal Proofs, Parallel Execution & 17-Language Comparison
Target toolchain: Bend 2.0.39, updated October 27, 2026. See the release milestones and captured primary sources for shipped changes and separately identified development commits.
Bend is a statically typed, affine functional
programming language created by Victor Taelin and HigherOrderCO (github.com/bendlang/bend).
It combines dependent types and machine-checked mathematical proofs
(LAWS.bend and PROOF.bend) with lock-free
parallel execution across multi-core CPUs and GPUs via the
BendRT runtime.
On October 23, 2026, developer Kevin Ngo
(@kevin_t_ngo) published a two-minute community explainer
demonstrating why autonomous coding agents prefer Bend, with every frame
of the animation drawn by a custom renderer written in
Bend:
“Just found out about Bend, so I had Claude make an explainer on why agents might prefer it. Every frame was drawn in Bend. Claude built a custom renderer in Bend to make the video.”
Kevin Ngo (@kevin_t_ngo), Original Post on X (Oct 23, 2026)
This guide covers Bend’s core capabilities: pure functions, algebraic
data types, dependent types, the LAWS.bend and
PROOF.bend verification workflow, compiler termination and
ownership rules, all 16 Apple M4 Max hardware
benchmarks, and a 17-language comparison
matrix linking directly to our dedicated deep-dive guides on
bend2.org.
Table of Contents
- 1. Functions, Algebraic Data Types, and Dependent Types
- 2.
Agent Verification Workflow:
LAWS.bend,PROOF.bend, andgen - 3.
Proof Checking Speed:
0.38 sVerification andbend --verdict - 4. Compiler Rules for Sound Proofs and Lock-Free Execution
- 5.
Parallel Execution (
!) Across CPU Threads and GPU Warps - 6. What the Benchmarks Show & Where Bend Is Not a Fit
- 7. Bend Compared with 17 Languages
1. Functions, Algebraic Data Types, and Dependent Types
In Bend, types, executable code, and mathematical proofs live in the
same language. Pure functions transform immutable algebraic data types
(type ... is Data:), while external side effects such as
file, network, or terminal I/O are isolated inside the IO
monad on the host CPU.
Because Bend is built on a dependent type theory (BendTT),
a type can depend on runtime values and program expressions: -
Value-Indexed Types: A vector type
Vec(T, n) carries its length n: Nat in the
type signature so out-of-bounds indexing is rejected at compile time. -
Propositions as Types (law and
def): An equality between two expressions
a == b : T is a first-class type. A law
declaration states the theorem as a type signature, and a matching
def of the same name supplies the constructive proof term
that inhabits that type.
Complete
Runnable Example: Why One Law Is Not Enough
(order.bend)
Introductory notes often demonstrate Bend with an order-cancellation
state machine (Pending, Cancelled,
Shipped) and a single idempotence law
(cancel(cancel(order)) == cancel(order)). However,
idempotence alone is satisfied by a broken no-op function that returns
its input unchanged
(def cancel(order: Order) -> Order: order).
To prevent an AI coding agent from reward-hacking the specification,
you write a law pair: one law proving state-transition
correctness (cancel is idempotent and converts
Pending into Cancelled), and a second law
proving data conservation (order_number is preserved across
all transitions):
import Base
type Order is Data:
Pending {number: U32}
Cancelled {number: U32}
Shipped {number: U32}
def order_number(order: Order) -> U32:
match order:
case Pending{number}: number
case Cancelled{number}: number
case Shipped{number}: number
def cancel(order: Order) -> Order:
match order:
case Pending{number}: Cancelled{number}
case Cancelled{number}: Cancelled{number}
case Shipped{number}: Shipped{number}
# Law 1: Applying cancel twice is identical to applying cancel once
law cancel_idempotent:
all order: Order
cancel(cancel(order)) == cancel(order) : Order
def cancel_idempotent(order: Order) -> cancel(cancel(order)) == cancel(order):
match order:
case Pending{number}: finally
case Cancelled{number}: finally
case Shipped{number}: finally
# Law 2: Cancelling a Pending order must produce a Cancelled order with the same U32 number
law cancel_pending_exact:
all number: U32
cancel(Pending{number}) == Cancelled{number} : Order
def cancel_pending_exact(number: U32) -> cancel(Pending{number}) == Cancelled{number}:
finally
# Law 3: Cancellation preserves the order number across all three states
law cancel_preserves_number:
all order: Order
order_number(cancel(order)) == order_number(order) : U32
def cancel_preserves_number(order: Order) -> order_number(cancel(order)) == order_number(order):
match order:
case Pending{number}: finally
case Cancelled{number}: finally
case Shipped{number}: finally
Save this file as order.bend and run
bend order.bend. In each branch, the BendTT evaluator
reduces both sides of == to identical normal forms
(Cancelled{number} and number), so
finally (or {==}) discharges the proof
obligation in milliseconds. If an AI agent alters
Cancelled{number} to return Pending{number},
or drops number to 0,
bend order.bend immediately rejects the file.
2.
Agent Verification Workflow: LAWS.bend,
PROOF.bend, and gen
In an agent-assisted codebase, humans declare specifications in
LAWS.bend, while coding agents write the implementation and
PROOF.bend. Four language features make this verification
loop practical in production repositories:
1. Exhaustive
Bounded Testing (gen) Before Proving
Writing an inductive proof for a false statement wastes millions of
agent tokens. Before constructing a formal proof in
PROOF.bend, an agent can use Bend’s built-in
gen keyword to exhaustively enumerate all inhabitants of an
algebraic data type up to a given recursive depth and test whether a
property holds across every generated value. If a law fails on depth-3
inputs, gen surfaces the exact counterexample immediately
so the agent can fix the bug before attempting a proof.
2.
Structural Induction and rewrite on Recursive Types
In order.bend, every constructor wraps a non-recursive
scalar (U32), so pattern matching the three cases and
writing finally completes the proof by direct evaluation.
When proving laws over recursive types such as natural numbers
(Nat), linked lists (List(T)), or binary trees
(Tree(T)), evaluation alone cannot reduce an open variable
inside a recursive call. Instead, the agent writes a recursive proof
function that matches on the inductive case (case 1n + p:),
invokes the proof function recursively on p to obtain the
inductive hypothesis, and uses rewrite to substitute the
proven equality into the goal type.
3.
Unfinished Proof Holes (?name) for Incremental Agent
Feedback
When an agent is constructing a multi-step proof, it does not have to
guess the entire proof term blindly. Placing a typed hole
(?todo) inside any branch causes bend to print
the exact expected goal type and every local variable in scope at that
branch, while still exiting non-zero (1 TODO found) so an
incomplete proof can never pass CI.
4.
Securing the CI Gate (@unsafe, main, and
bend-lint 2.0.38)
By convention, LAWS.bend is read-only to the AI agent
(CODEOWNERS protected), while the agent edits the
application modules and PROOF.bend. To make the
verification gate fail-closed in CI: - Verify
import ./LAWS.bend is present in
PROOF.bend so an agent cannot pass the gate by deleting the
import. - Reject @unsafe and main in
PROOF.bend: If PROOF.bend defines
main, running bend PROOF.bend executes
main instead of printing "All terms check.",
and any reachable @unsafe definition prints an
"annotated as unsafe" warning. Requiring
[ "$(bend PROOF.bend)" = "All terms check." ] blocks both
bypasses. - bend-lint (Added in Bend
2.0.38): Release 2.0.38 ships
bend-lint, an AST linter supporting custom rules written in
Bend or TypeScript (using the OptionNum,
OptionFlag, and OptionText option
constructors) to enforce project-specific LAWS.bend and
module policies automatically.
3.
Proof Checking Speed: 0.38 s Verification and
bend --verdict
The single biggest bottleneck in agentic formal verification is checker latency. When an AI coding agent edits a function, it needs sub-second compiler feedback on whether its proof holds.
Prover Throughput on 3,200 Generic Instantiations (Apple M4 Max)
In the upstream verification throughput benchmark (checking
3,200 generic theorem instantiations on an Apple M4 Max),
Bend completes verification in 0.38 seconds:
| Proof Checker / Language | 3,200 Generic Instantiations (Apple M4 Max) | Relative Latency vs. Bend | Proof Checking Mechanism |
|---|---|---|---|
Bend
(bend) |
0.38 s | 1.0x (Baseline) | Direct normalization of explicit proof terms in BendTT |
| Rocq (Coq) | 6.00 s | 15.8x slower | Tactical proof script elaboration and kernel conversion checking |
| Lean 4 | 19.20 s | 50.5x slower | Typeclass resolution, simp
tactic search, and kernel verification |
| Agda | > 300.00 s (> 5 min) | > 789x slower | Unification and normal-form evaluation across indexed families |
| Isabelle/HOL | > 300.00 s (> 5 min) | > 789x slower | LCF tactic reconstruction and higher-order unification |
Everyday bend
vs. bend --verdict
Two design choices explain how Bend achieves that 0.38 s
inner loop and how to pair it with high-assurance release verification:
1. Zero Tactic Search Overhead: Lean 4
(simp, omega, aesop) and Rocq
(auto, lia) spend most of their wall-clock
time searching for proofs and elaborating implicit typeclasses. Bend has
no tactic language or proof search; the coding agent
writes explicit proof terms (match, induction,
rewrite, and finally), which the checker
normalizes and compares directly. 2. Everyday Checker
vs. Verdict Kernel: Use the everyday checker for iterative
feedback and the verdict kernel for an additional check. The pinned BendTT
formalization accompanies Bend 2.0.39. PR #1627 adds
adequacy for closed, live equality proofs in checked books. Its author
reports unchanged kernel output across 1,666 files. These model-level
guarantees do not replace application requirements or implementation
correspondence tests.
4. Compiler Rules for Sound Proofs and Lock-Free Execution
A language where ordinary functions double as mathematical proofs
cannot permit unrestricted infinite loops or arbitrary mutation. Bend
enforces six compile-time rules (guide/GUIDE.md):
- Structural Recursion Only: In dependent type
theory, a function that loops forever inhabits every type, including
False(0 == 1). Every recursive call in Bend must pass a syntactic sub-term of its pattern-matched input (case 1n + p:callingf(p), orcase Cons{head, tail}:callingf(tail)). - No Mutual Recursion: Functions cannot recurse
through multi-function cycles (
fcallinggcallingf). Long-running servers or event loops take an explicitNatfuel counter that decreases on each step. - Exhaustive Pattern Matching: Every
matchexpression must cover all constructors of the matchedDatatype; partial functions do not compile. - Affine Ownership (
Type : TypeWithout Paradox): Classical theorem provers (Lean 4, Rocq, Agda) require an infinite hierarchy of universe levels (Type 0 : Type 1 : Type 2) to prevent Girard’s paradox. BendTT eliminates universe levels (Type : Type) and prevents self-referential paradoxes by making all variables affine: every variable is used at most once by default, and higher-order function values (closures) can never be copied. - Explicit Counted Sharing (
&): First-order algebraic data (Data) can be used more than once only when explicitly annotated with&, which inserts deterministic reference-counted sharing without a tracing garbage collector. - Pure Core vs. Host
IOIsolation: Pure Bend functions cannot perform side effects. File, socket, and process effects live in theIOmonad on the host CPU, ensuring that pure functions are deterministic, confluent, and safe to execute on GPU warps.
5.
Parallel Execution (!) Across CPU Threads and GPU
Warps
When two independent expressions are bound side by side with
!, BendRT schedules them in parallel across CPU worker
threads or GPU warps:
def pow2(n: Nat) -> U32:
match n:
case 0n:
1
case 1n + p:
# Fork two independent recursive calls in parallel
a! b! = pow2(p) & pow2(p)
a + b
- Zero Locks or Data Races: Because affine ownership
guarantees that
pow2(p)andpow2(p)operate on disjoint data (or immutable&shared data), parallel tasks never contend on mutexes or atomic compare-and-swap loops. - Static
128x128Task Cube (16,384Tasks): Unlike Rust’sRayonor Go’s work-stealing scheduler, BendRT maps the binary fork tree onto a static128x128Task Cube (16,384lock-free rings) using fixed task assignment. As a result, parallel speedups are highest when recursive tree splits are balanced. - Compile Once for CPU or GPU: Running
bend main.bend -o mainerases all compile-time proofs and emits a self-contained C binary linked against BendRT. You control the execution target at runtime via./main +RTS --threads 8 --gpu off(multi-core CPU) or--gpu on(Apple Metal / NVIDIA CUDA).
6. What the Benchmarks Show & Where Bend Is Not a Fit
Bend’s upstream runtime benchmarks were measured on an Apple
M4 Max (data/bend-ecosystem.json). Game of
Life updates a grid of cells from their neighbors’ states; a
lexer converts source text into tokens:
| Workload | 1 CPU Thread | Parallel CPU | GPU |
|---|---|---|---|
| Game of Life | 7.803 s | 0.647 s | 0.063 s |
| Lexer | 2.144 s | 0.198 s | 1.075 s |
Methodology for this Bend 2.0.39 guide: the historical upstream
measurements are dated 2026-09-17 and were not rerun for
this update. They compare single-core CPU, multi-core CPU, and Metal
GPU, without hand-written CUDA (upstream workloads · benchmark explorer).
Across the complete 16-workload suite on the Apple M4 Max
(data/bend-ecosystem.json), the numbers highlight
both where Bend excels and where it loses: -
Single-Core Overhead (0.23x to 0.99x
vs. C -O3): On 1 CPU thread
(SEQ-CPU), Bend is slower than clang -O3 on
15 of 16 benchmarks (~1.3x slower
geometric mean) and 4.4x slower on
HAMT Hashmap (0.23x), because Bend
allocates immutable heap tree nodes instead of mutating flat contiguous
arrays in place. - GPU Warp Divergence (0.18x to
0.98x GPU vs. Parallel CPU on 5 of 16 Workloads):
On regular grid, particle, and balanced tree workloads,
PAR-GPU reaches up to 123.9x over
SEQ-CPU (10.3x faster than
PAR-CPU). However, on 5 of the 16
benchmarks (Tree MatMul, N-Queens,
Symbolic Regression, HAMT Hashmap, and
Regex Lexer), GPU execution is slower than
multi-core CPU (PAR-CPU), and on
Regex Lexer the GPU (1.075 s) is even slower
than single-threaded C (1.036 s).
| Workload | Category | Bend SEQ-CPU (1 Thread) |
Bend PAR-CPU
(Multi-Core) |
Bend PAR-GPU (Metal
GPU) |
Native C -O3 (1 Thread) |
1-Core Bend vs. C -O3 |
GPU vs. PAR-CPU |
Best Execution Target |
|---|---|---|---|---|---|---|---|---|
| Game of Life | Cellular Automata | 7.803 s | 0.647 s | 0.063 s | 6.776 s | 0.87x (slower) |
10.27x | PAR-GPU
(123.9x vs SEQ) |
| N-Body Physics | Particle Gravity | 5.758 s | 0.516 s | 0.059 s | 5.126 s | 0.89x (slower) |
8.75x | PAR-GPU
(97.6x vs SEQ) |
| Mandelbrot | Escape-Time Fractal | 4.473 s | 0.395 s | 0.057 s | 3.750 s | 0.84x (slower) |
6.93x | PAR-GPU
(78.5x vs SEQ) |
| Merkle Tree | Cryptographic Tree | 4.222 s | 0.422 s | 0.071 s | 3.423 s | 0.81x (slower) |
5.94x | PAR-GPU
(59.5x vs SEQ) |
| 3D Raytracer | Computer Graphics | 4.616 s | 0.396 s | 0.151 s | 3.646 s | 0.79x (slower) |
2.62x | PAR-GPU
(30.6x vs SEQ) |
| Terrain Mesh | Procedural Content | 2.225 s | 0.197 s | 0.106 s | 2.198 s | 0.99x (slower) |
1.86x | PAR-GPU
(21.0x vs SEQ) |
| Parallel BFS | Graph Algorithms | 3.918 s | 0.343 s | 0.207 s | 3.585 s | 0.92x (slower) |
1.66x | PAR-GPU
(18.9x vs SEQ) |
| Edit Distance | Dynamic Programming | 2.559 s | 0.236 s | 0.144 s | 2.002 s | 0.78x (slower) |
1.64x | PAR-GPU
(17.8x vs SEQ) |
| Bitonic Sort | Sorting Networks | 6.043 s | 0.799 s | 0.450 s | 5.719 s | 0.95x (slower) |
1.78x | PAR-GPU
(13.4x vs SEQ) |
| Tree Radix Sort | Sorting Networks | 4.083 s | 0.445 s | 0.314 s | 2.791 s | 0.68x (1.5x
slower) |
1.42x | PAR-GPU
(651 MB RSS) |
| K-Means | Machine Learning | 2.069 s | 0.268 s | 0.191 s | 2.062 s | 0.99x (slower) |
1.40x | PAR-GPU
(10.8x vs SEQ) |
| Tree MatMul | Linear Algebra | 2.064 s | 0.226 s | 0.231 s | 2.964 s | 1.44x (faster) | 0.98x (GPU
slower) |
PAR-CPU (quadtree overhead) |
| N-Queens | Combinatorics | 5.406 s | 0.455 s | 0.933 s | 3.599 s | 0.67x (1.5x
slower) |
0.49x (2.0x
slower) |
PAR-CPU (GPU diverges) |
| Symbolic Reg. | Genetic Algorithms | 3.014 s | 0.266 s | 0.529 s | 2.208 s | 0.73x (1.4x
slower) |
0.50x (2.0x
slower) |
PAR-CPU (GPU diverges) |
| HAMT Hashmap | Data Structures | 2.741 s | 0.238 s | 0.521 s | 0.622 s | 0.23x (4.4x
slower) |
0.46x (2.2x
slower) |
Native C (1T) / PAR-CPU |
| Regex Lexer | Compilers & Text | 2.144 s | 0.198 s | 1.075 s | 1.036 s | 0.48x (2.1x
slower) |
0.18x (5.4x
slower) |
PAR-CPU (GPU < 1-core C) |
When Bend Is Not a Better Fit (Where Other Languages Win)
Bend is designed for balanced recursive algorithms that benefit from
machine-checked invariants (LAWS.bend). It is
not the right choice for every workload
(data/bend-ecosystem.json):
- In-Place Hash Tables & Flat-Array Pointer Workloads
(
Hashmap,Tree Radix Sort):- Benchmark evidence: On
HAMT Hashmap, single-core Bend (2.741 s) is4.4xslower than nativeC -O3(0.622 s),3.1xslower than TypeScript on V8 (0.892 s), and1.8xslower than Lean 4 (1.526 s) (data/bend-ecosystem.json). Because Bend is purely functional and represents maps as persistent trees rather than flat open-addressed arrays, every insert or lookup chases tree pointers. Similarly,Tree Radix Sortallocates recursive tree nodes totaling651 MBRSS (1.46xslower than single-core C). - Better fit: Rust, C, or C++ with cache-aligned
contiguous arrays (
Vec<T>,SwissTable/HashMap).
- Benchmark evidence: On
- Branch-Heavy Sequential State Machines & Backtracking on
GPU (
Lexer,N-Queens,Symbolic Regression):- Benchmark evidence: On
Regex Lexer, running Bend on the Apple M4 Max GPU (1.075 s) is5.4xslower than BendPAR-CPU(0.198 s) and slower than single-threaded C (1.036 s) (data/bend-ecosystem.json). OnN-Queens(0.933 sGPU vs.0.455 sCPU) andSymbolic Regression(0.529 sGPU vs.0.266 sCPU), the GPU is2.0xslower than multi-core CPU because irregular branching causes SIMT warp divergence and unbalanced trees leave cells idle in BendRT’s static128x128Task Cube. - Better fit: Multi-core CPU with work stealing
(Rust
Rayon, C++) or BendPAR-CPU(--gpu off).
- Benchmark evidence: On
- Dense Matrix Multiplication, Tensor Cores &
FP64Scientific Computing (Tree MatMul):- Benchmark evidence: The historical
Tree MatMulresult hasPAR-GPU(0.231 s) slightly slower thanPAR-CPU(0.226 s,0.98x) with recursive quadtrees (data/bend-ecosystem.json). These timings were not rerun on Bend2.0.39. The release notes do not announce Tensor Core intrinsics or anF64type. - Better fit: CUDA & Metal,
Mojo,
Python
(
PyTorch/JAX/Triton), or Julia.
- Benchmark evidence: The historical
- High-Concurrency Network Servers, Databases & Stateful
Async I/O:
- Architectural limit: In Bend,
IOruns sequentially on the host CPU outside theBendTTproof kernel and GPU runtime (data/bend-ecosystem.json). Long-running server loops require explicitNatfuel to pass the structural termination check, and there is no non-blockingepoll/kqueuereactor. - Better fit: Go
(
goroutines), Rust (Tokio), or Elixir / Erlang (BEAM).
- Architectural limit: In Bend,
- Deep Mathematical Proofs Requiring Tactics, SMT Automation,
or Floating-Point Proofs:
- Architectural limit: Bend has no tactic
language (
simp,omega,aesop), no automated proof search, and treatsF32operations as axiomatic (F32rounding and numerical bounds cannot be proved inLAWS.bend) (data/bend-ecosystem.json). - Better fit: Lean 4
(
Mathlib) for deep mathematics or AWS Cedar (cedar symcc) for SMT-backed authorization policy verification.
- Architectural limit: Bend has no tactic
language (
7. Bend Compared with 17 Languages
Select any language in the first column below to open its dedicated
engineering deep-dive comparison on bend2.org:
| Language | Execution & Memory | CPU Parallelism | Sharing & Effects | Correctness Checks | GPU Execution |
|---|---|---|---|---|---|
| Bend → | Native C via BendRT;
affine ownership with & counted sharing. |
Balanced ! forks across
static 128x128 Task Cube; no work stealing. |
Disjoint owned sub-trees in forks;
IO monad runs on host. |
Dependent types (BendTT);
explicit proofs of LAWS.bend in 0.38
s. |
Same Bend functions via !
compiled to Metal or CUDA. |
| Lean 4 → | Native C compilation with reference counting and persistent data structures. | Explicit Task futures on a
runtime thread pool. |
Immutable sharing; IO tasks
coordinate via channels or mutexes. |
Full Calculus of Inductive Constructions,
Mathlib, and tactics (simp,
omega). |
External FFI bindings
(SciLean); no built-in GPU kernel compiler. |
| Rust → | Native LLVM code; affine ownership, lifetimes, and borrow checking. | OS threads, Rayon
work-stealing thread pools, and Tokio async. |
Borrowed slices (&[T]),
Arc<Mutex<T>>, or message channels. |
Send/Sync
prevent data races; application proofs require Verus or Kani. |
Separate rust-gpu /
wgpu / CUDA crates; CPU closures do not auto-compile to
GPU. |
| Python → | Bytecode interpreter with reference counting and cyclic GC. | multiprocessing, C
extensions, or free-threaded 3.13t/3.14t;
default GIL serializes bytecode. |
Shared mutable heap objects requiring locks across threads. | Dynamic typing; optional external static
type checkers (mypy, pyright). |
Dispatches pre-compiled C++/CUDA kernels
via PyTorch, JAX, or Triton. |
| CUDA & Metal → | Device-specific SIMT C++ / MSL kernels with manual global/shared memory. | Host-side OpenMP or thread pools orchestrated separately. | Explicit host-to-device DMA buffers,
barriers (__syncthreads()), and atomics. |
No built-in proof system; manual race and barrier auditing. | Maximum low-level hardware control over thread blocks, warps, and tensor cores. |
| Mojo → | MLIR/LLVM native code with owned values, references, and deterministic destruction. | Explicit parallelize tasks on
a work-stealing thread pool + explicit SIMD vectors. |
Mutable-reference exclusivity; explicit device buffers and synchronization. | Static types, traits, and
@parameter specialization; no dependent proof checker. |
User-written GPU kernels exposing explicit
DeviceContext, blocks, and thread indices. |
| C (ISO C11) → | Ahead-of-time native machine code; manual
malloc/free pointer management. |
pthreads or
OpenMP pragma loops. |
Unrestricted shared mutable memory; manual mutexes and atomics. | Weak nominal types; external model
checkers (CBMC, Frama-C) required for
proofs. |
Requires switching to CUDA, OpenCL, or OpenMP target offload. |
| C++ (C++20/23) → | Native code with RAII, templates,
constexpr, and manual/smart pointers. |
std::jthread,
<execution> parallel STL (par_unseq),
and TBB work stealing. |
Shared mutable memory;
std::atomic, mutexes, and lock-free queues. |
concepts and
static_assert; no dependent equality proofs. |
stdpar, SYCL, Kokkos, or CUDA
C++ device kernels. |
| Go → | Native code with concurrent mark-sweep garbage collection. | M:N work-stealing scheduler multiplexing
lightweight goroutines. |
Shared heap memory coordinated via CSP
chan channels or sync.Mutex. |
Simple structural interfaces and generics;
runtime -race detector. |
No native GPU compilation; requires CGo bindings to CUDA/Metal. |
| Haskell (GHC) → | Native code with lazy graph reduction and generational GC. | Pure par/pseq
sparks and green threads on the GHC runtime. |
Immutable persistent values;
STM (Software Transactional Memory) and
MVar. |
GADTs, type families, and
LiquidHaskell SMT refinement types. |
Embedded array DSLs
(Accelerate, Futhark FFI); par
sparks stay on CPU. |
| OCaml 5 / Elixir / Erlang → | OCaml 5 native/GC domains; BEAM VM per-process heaps. | OCaml Domainslib
work-stealing; BEAM preemptive actor schedulers. |
OCaml immutable sharing + atomics; BEAM share-nothing message passing. | Hindley-Milner / GADTs (OCaml) or Dialyzer specs; no dependent kernel proofs. | External Nx / XLA bindings
(Elixir) or C stubs. |
| Java (HotSpot) → | JVM JIT compilation with generational
garbage collection (G1/ZGC). |
OS threads, ForkJoinPool work
stealing, and Project Loom virtual threads. |
Shared mutable heap with
synchronized, volatile, and
java.util.concurrent. |
Nominal generics and runtime bounds checks; JML/KeY for external verification. | Project Babylon / TornadoVM or JNI
bindings; ForkJoinPool runs on CPU. |
| C# (.NET) → | CLR RyuJIT native compilation with
generational GC and value structs. |
Task Parallel Library
(Parallel.ForEach), work-stealing thread pool. |
Shared heap with
Span<T>, lock, and
Interlocked atomics. |
Nullable reference types and code contracts; no dependent proof kernel. | ILGPU / ComputeSharp or native P/Invoke wrappers. |
| TypeScript → | V8 / Bun JIT compilation with garbage collection. | Single-threaded event loop; explicit
Worker threads for CPU parallelism. |
SharedArrayBuffer +
Atomics or structured-clone message passing. |
Erased structural type system; no kernel proof verifier. | WebGPU (WGSL shaders) via
browser or native bindings. |
| JavaScript → | V8 / JavaScriptCore JIT with generational garbage collection. | Single-threaded async event loop + Web Workers. | Message passing or
SharedArrayBuffer across isolated worker heaps. |
Dynamic runtime checks only. | WebGL / WebGPU compute shaders written in GLSL/WGSL. |
| Julia & MATLAB → | LLVM JIT compiled multiple dispatch with garbage collection. | Threads.@threads and
task-based multithreading. |
Shared mutable arrays; user responsible for avoiding race conditions. | Dynamic multiple dispatch with optional type assertions. | First-class array/kernel programming via
CUDA.jl, AMDGPU.jl, and
Metal.jl. |
| Swift → | LLVM AOT compilation with deterministic Automatic Reference Counting (ARC). | Swift 6 Structured Concurrency
(async let, TaskGroup) on cooperative
pool. |
Strict actor isolation and
compile-time Sendable checking. |
Strong value semantics and data-race safety; no theorem proving. | Separate Metal Shading Language
(.metal) kernels dispatched via
MTLDevice. |
| AWS Cedar → | Rust interpreter evaluating stateless authorization policies. | Host-managed thread pool invoking stateless evaluation calls. | Pure read-only entity store and context JSON evaluation. | Formally verified in Lean 4 with
SMT-backed cedar symcc policy analysis. |
CPU-only authorization evaluator. |
Related
Architecture & Verification Guides on bend2.org
- Anthropic’s 180-Million-Line Formal Verification Milestone: Why Bend 2 Was Invented for Exactly This
- Bend 2 Strengths, Weaknesses, and Production Decision Guide
- StrictDoc + Bend 2: Full-Lifecycle Requirements Traceability and Formal Proof Stack
- DevSecOps Parallel Policy Evaluation with Bend 2 and Rust