Console output (io)
io:format/1,2,3, io:fwrite/1,2,3, io:put_chars/1,2 and io:nl/0,1 are runtime builtins
registered under module io in the bridge catalog. Formatting uses the
io_lib engine to produce and flatten io_lib:format/2 output. The ~p
control uses OTP's io_lib_pretty layout rules, implemented in
io_lib/pretty.cpp. The io input functions are
implemented in Erlang in the library.
Calls
io:format(Format)is equivalent toio:format(Format, []). Both returnok.io:fwrite/1,2,3are equivalent toio:format/1,2,3;io:nl/0,1write a newline.io:format/3,io:fwrite/3,io:put_chars/2andio:nl/1accept an output device.standard_ioanduserselect standard output.standard_errorselects standard error; standard output is flushed before a standard error write to preserve write order.- A pid, or an atom registered to a pid, identifies an I/O server. Output is sent through
clause_io:put_chars/2as an I/O protocol{put_chars, unicode, Utf8}request. The server writes the text using its configured encoding, and the call returns the server's reply. An unregistered atom raisesbadarg; a dead pid raiseserror:terminated; the caller's own pid raiseserror:calling_self; any other device term raisesfunction_clause, matching OTP. io:put_chars(Chardata)accepts Unicode characters, UTF-8 binaries and nested lists terminated by[]or a binary. Invalid chardata, including atoms, surrogate code points, invalid UTF-8 and non-byte-aligned bitstrings, raisesbadarg.- Output is constructed in full before it is written as UTF-8, matching OTP's standard output
device with encoding
unicodein-noshellmode. Formatting or validation errors produce no output. A rejected write causes the runtime failureoutput_failure, with exit status 70. - Qualified calls,
fun io:format/2,apply(io, format, Args)andM:format(...)resolve to the builtins. A compilation batch containing a module namediodoes not replace these builtins; OTP'siomodule is sticky. See registration.
Formats
Formataccepts an atom interpreted as its characters, a binary interpreted as Latin-1 bytes, or a list. A non-character list element is emitted as literal chardata without control-sequence interpretation. Such an element advances the tracked column by one, matching OTP.- Control sequences have the form
~F.P.PadModC: field widthF, precisionP, padding characterPad, modifiersModand control characterC. A negative width or-selects left adjustment.*obtains an integer parameter or padding character from the argument list. Supported modifiers aret(Unicode),l(disable string detection),k(ordered maps) andK(map order supplied as an argument:orderedorreversed). Comparison functions forKraisebadarg. Maps are printed in key order. - All OTP 29 controls and their field rules are supported:
~w ~W ~p ~P ~s ~e ~f ~g ~b ~B ~x ~X ~+ ~# ~c ~i ~n ~~.~struncates or pads to precisionPwithin field widthF.~wand integer and float controls emit*characters when the result exceedsF.~crepeats a character; integer controls usePas the base, in the range 2..36;~nwith widthFemitsFnewlines. Widths are measured according toio_lib:chars_length/1. - Without
t,~saccepts only Latin-1 characters,~cemits the low byte of its integer argument, and~w/~pescape atom characters outside Latin-1 as\x{...}. Witht,~sinterprets binaries as UTF-8 with Latin-1 fallback, and~prenders printable UTF-8 binaries as<<"..."/utf8>>. - Inputs rejected by
io_lib:format/2raisebadarg. These include unknown control characters, missing or excess arguments, arguments of an incorrect type,Fsmaller thanP, left adjustment for~por~n, and integer bases outside 2..36. Output that is not valid Unicode also raisesbadarg.
Pretty printing (~p)
Fspecifies the line length, with a default of 80; 0 disables line breaks.Pspecifies the initial column. WhenPis absent, formatting uses the current output column, with tab stops at multiples of 8.~Plimits traversal according to its depth argument. Thechars_limitoption ofio:format/3andio_lib:format/3limits each control to its allocated share of the character budget. Omitted content is represented by..., matching OTP.- Terms are converted to OTP's intermediate representation, which records each value's length
when rendered on one line. Strings, printable binaries, atoms and numbers are represented as
text. String detection uses flat lists of printable Latin-1 characters, corresponding to the
default
io:printable_range(). - Content that fits within the remaining line width is emitted without line breaks. Lists and
tuples break between elements and align after the opening bracket. Tagged tuples (
{atom, ...}) align after the tag, or use indentation of 4 or 1 when tag alignment would exceed half the line width. Map pairs and native record fields place the value on the next line when necessary. Long binaries wrap between bytes. - Container nesting deeper than 256 raises
system_limitbecause layout traversal uses native stack recursion. - Formatting completes without yielding, regardless of term size. See portions.
Clause