Clause
← All documentation

Builtins

Plan 11 step 36 (2026-10-07): the production builtin bridge. Builtins are erlang functions the runtime implements in C++. The runtime registers them by module, function and arity; generated code reaches them directly, through dynamic calls and as fun values.

Which builtins exist

The bridge catalog abi::v1::bridge_builtins (builtins.hpp) lists every builtin both the compiler and the runtime know:

Entries are only appended: an entry's index is the number generated code passes to the bridge service. A qualified call of a catalog builtin of another module (io:format(F, A)) also calls the bridge. Other erlang functions keep their diagnostics: a direct call of an unknown one is unknown module erlang, fun erlang:F/A or fun F/A of a guard BIF outside the catalog (node/0) and fun erlang:apply/2,3 report the unavailable dynamic calls capability.

How calls reach them

SourcePath
abs(X), X + Y, erlang:display(X), halt(), error(R)Inline services, as before the bridge
erlang:function_exported(M, F, A), setelement(I, T, V), A ++ B, A -- B, length(L) in a body (catalog builtins without an inline service)Entered like a function: CLAUSE_builtin_frame_v1(context, index) gives the builtin's frame, the arguments go in the registers (portions)
fun abs/1, fun erlang:'+'/2External fun erlang:F/A; registration binds it to the builtin
M:F(Args), apply(M, F, Args), runtime fun M:F/AThe code server finds a module's export first, then a builtin

Portions

Plan 11 step 43A (2026-10-08): builtins whose work grows with a list or binary argument run in bounded portions, like OTP's trapping BIFs, so a long builtin cannot keep other processes from running (processes).

BuiltinPortions
length/1 in a bodyCounts cells; in a guard it stays the inline service, as OTP's guard BIF does not trap
A ++ BCollects A's elements, then builds the copy onto B from its end
A -- BCollects B, sorts it by exact order (bottom-up merge sort), scans A with a binary search per element, then builds the kept elements; when nothing is removed the result is A itself
binary_to_list/1Builds the list from the binary's end
list_to_binary/1, iolist_to_binary/1Walks the iolist depth first, then makes the binary at once

Other builtins run to completion. The tuple builtins (setelement/3, make_tuple/2,3, tuple_to_list/1, list_to_tuple/1) do as in OTP: their work is bounded by the tuple arity limit. The remaining conversions read inputs bounded by the atom, integer and float limits. Formatting with io:format/1,2 runs to completion (differences). Inline services of loops (a comprehension's final reverse) run to completion as part of the loop.

Typed builtins

Plan 11 step 41 (2026-10-07): builtins that check their own arguments are C++ functions of typed parameters (typed.hpp), Result Function(ProcessContext &, Parameters...), registered with typed_entry<Function>(module, name) (the arity is the parameter count).

Registration