Clause

Erlang/OTP 29, compiled to native code

Clause is an ahead-of-time compiler for Erlang. It preprocesses, parses and analyzes Erlang source, compiles it through LLVM and links native executables with its own runtime: lightweight processes on several scheduler threads, message passing, ports and per-process garbage collection.

Work in progress: Erlang/OTP 29 programs compile to native executables that run on Windows and Linux today, with Clause's own stdlib, kernel, crypto and ssl. Still to come: macOS Apple Silicon and native ARM hardware, OTP's own test suites, source file and line locations in stack traces, and more optimization; distribution and hot code loading are not supported. The benchmarks page shows where Clause stands against OTP; the documentation lists what works and where Clause differs.

Features

Feature details

Frontend

  • Erlang/OTP 29 syntax: records, maps, bitstrings, comprehensions, types and specifications
  • Macros, includes and conditional compilation
  • Parse transforms without an Erlang/OTP install: ms_transform, qlc, merl and your own
  • ASN.1 specifications compiled into modules as asn1ct does: BER, DER, PER and UPER

Erlang semantics

  • Pattern matching and guards in clauses, case, if and receive
  • Records, funs, maybe and list, binary and map comprehensions
  • Exceptions with try, catch and stack traces

Compiler

  • Type inference with per-clause function types
  • LLVM O0, O2 and Os, with link-time optimization across modules
  • O2 removes type checks proven by inference
  • O2 inlines small local functions, known funs and lists loops
  • Proper tail calls and deep recursion
  • Parallel code generation on every hardware thread

Runtime

  • C++23 runtime with all Erlang term types, arbitrary-precision integers included
  • Processes, selective receive, links, monitors and timers on several scheduler workers
  • Per-process heaps with a copying garbage collector
  • Concurrent ETS tables in C++

OTP library

  • Clause's own OTP 29 modules with OTP's exports, results and error reasons
  • gen_server, gen_statem, gen_event, supervisor, application and logger
  • stdlib: lists, maps, string, binary, json, re, rand and the collection modules
  • ets, dets, disk_log, zip and erl_tar with files as OTP writes them
  • erl_scan, erl_parse, erl_lint, erl_eval, qlc and compile at run time, with compiled modules interpreted
  • syntax_tools: erl_syntax, erl_prettypr, epp_dodger and merl
  • kernel: file, gen_tcp, gen_udp, inet, inet_res and os
  • crypto over OpenSSL with FIPS mode; public_key with certificate path, CRL and OCSP validation
  • ssl: TLS 1.2 and 1.3 connections over OpenSSL's libssl

Projects and tooling

  • One clau command from Erlang source to a native executable
  • TOML projects with SQLite build caches
  • Interactive Erlang shell with clau --shell
  • Debug info with -g (CodeView or DWARF 5) and profiling with --profile
  • Tested against the reference Erlang/OTP and benchmarked against OTP