format
(format destination control-string args...)
A subset of Common Lisp's format, implemented as a macro shared by the
interpreter and both compilers. A literal control-string is expanded at compile
time; a computed one is rendered at run time (see Runtime control
strings), with the same directives either way. With
destination t the form expands into princ/prin1/terpri calls, writes to
standard output, and returns nil; with destination nil it builds and returns
the formatted string (expanding into princ-to-string/prin1-to-string calls
folded with the internal string concatenation); with any other destination
expression it builds the string the same way and then DISPATCHES on the value at
run time -- a stream is written with one write-string call and nil is returned
(a with-output-to-string string stream or a file stream), a t value writes to
*standard-output*, and a nil value returns the string. That test has to happen
at run time because nil does not name a stream: it is the "return the string"
destination, so a function that forwards its own &optional stream argument
((defun render (x &optional stream) (format stream ...)), the Common Lisp
convention) answers a string when called without one. All arguments are evaluated left to right before any output.
Hello WORLD, you are 42!
With destination nil the result is returned as a string instead of printed:
Directives
| Directive | Meaning |
|---|---|
~a, ~A | Aesthetic: prints the argument like princ (strings without quotes). With :, nil prints as () |
~s, ~S | Standard: prints the argument like prin1 (readable; a string is quoted and its embedded " / \ escaped). With :, nil prints as () |
~w, ~W | Write: prints the argument like write -- prin1 under the printer control variables. It takes no prefix parameters, and its modifiers bind variables the printer does not honor (~:W binds *print-pretty*, ~@W unbinds *print-level*/*print-length*), so all three spellings print the same text |
~d, ~D | Decimal integer. With :, digits are grouped with commas; with @, a + sign precedes non-negative values |
~x, ~o, ~b | Hexadecimal / octal / binary integer (uppercase digits), with the same parameters and modifiers as ~d |
~R | Radix: ~NR prints the integer in radix N (2-36). Without the radix parameter the decimal digits are printed (English cardinal/ordinal output is not implemented) |
~c, ~C | Character: prints the glyph like write-char. With @, the #\ reader syntax (like prin1); with :, non-graphic characters print their name (Newline, Space, ...) |
~f, ~F | Fixed-format floating point. ~,Df prints D digits after the decimal point (rounded); with @, a leading +. Full parameters: ~w,d,k,overflowchar,padchar F |
~e, ~E | Exponential (scientific) floating point: [-]d.ddde[+/-]xx. ~,De prints D digits after the decimal point (default 6, rounded); with @, a leading +. Full parameters: ~w,d,e,k,overflowchar,padchar,exponentchar E (k must be 1) |
~g, ~G | General floating point: the plain float representation for magnitudes in [0.1, 1e16) (and zero), the ~e form otherwise |
~$ | Monetary: ~D$ prints D digits after the decimal point (default 2); with @, a leading + |
~% | Newline (one, or the count given by a prefix parameter) |
~& | Fresh line: a newline only if not already at the start of a line |
~~ | A literal ~ |
~(str~) | Case conversion of the processed str: downcase; ~:( capitalizes every word, ~@( capitalizes only the first word, ~:@( upcases |
~[str0~;str1~:;default~] | Conditional: the argument (an integer) selects a clause; ~:; introduces the default. ~N[ / ~#[ select by a literal / by the number of remaining arguments; ~:[false~;true~] tests nil; ~@[str~] processes str (re-using the tested argument) only when it is non-nil |
~{str~} | Iteration: applies str repeatedly to the elements of the list argument. ~N{ caps the passes at N; ~:{ iterates over a list of sublists; ~@{ iterates over the remaining arguments; ~:@{ treats each remaining argument as a sublist |
~? | Recursive format: consumes a control string and a list of its arguments, rendered through the runtime renderer. ~@? takes the inner control's arguments from the remaining arguments instead of a list |
~* | Argument jump: ~N* skips N arguments (default 1), ~N:* moves back N, ~N@* jumps to argument N (default 0) |
Directives accept prefix parameters (written after the ~, comma-separated) and
the :/@ modifiers. A parameter is a decimal number, a character ('c), v
(consume an argument and use its value), or # (the number of remaining
arguments). Field directives (~a/~s/~d/~x/~o/~b/~f/~e/~$) take
a leading minimum-width parameter; text shorter than the width is padded (with
the pad-character parameter -- a 'c literal or a runtime v -- space by
default). ~a/~s pad on the right (left with @); numbers pad on the left.
Hello WORLD, you are 42 years old.
1,000,000 and +42
3.14 and 3.14
1.2345e+3 and 3.1416e+0
foo |00042|
"str" and str
Hello WORLD!
FF 100 101 10000
a #\b Newline
foo bar Foo Bar
one yes x=42
<1><2> (X,1)(Y,2) A B
1, 2, 3
1 1
Limitations
Other destinations (strings with fill pointers) are not supported. The loop escape ~^ is
supported at the top level and inside ~{ ... ~} / ~@{ ... ~} bodies (the
join idiom "~{~a~^, ~}"; inside ~:{ ... ~} it ends the current sublist's
body), but its ~:^/~@^ variants and prefix parameters are not. Further notes:
- A
~f(and the fixed branch of~g) without a digit count falls back to the free-format float printing (the shortest round-trip decimal, identical on every backend), which may use exponent notation where~fwith a digit count never would; supply a digit count for a fixed decimal layout.~gaccepts no prefix parameters. ~ebuilds its mantissa from integer arithmetic (so the output is identical on every backend) and the digit count must be a literal, not a runtimev. The scaled mantissa is computed in 64-bit arithmetic, which limits~,Deto roughlyD<= 17 digits of precision (identically on every backend); the default (~e, 6 digits) is well within that bound. The scale factor of~emust be 1 (the default), and the overflow character of~f/~erequires a literal width.- The repeat count of
~%/~&/~~must be a literal or#(a runtimevcount there is not supported).~&decides whether to emit a newline from the actual output column for destinationt, but from the surrounding literal text (a static approximation) for destinationniland inside composite (~(/~[/~{) bodies. - Composite directives nest freely: a
~[conditional may hold another~[(or a~{ ... ~}iteration) in any of its clauses. When a runtime-selected~[has clauses that consume DIFFERENT numbers of arguments, the rest of the control string is expanded once per clause so each branch continues from its own argument position, exactly as Common Lisp's argument pointer would. A branch that would need more arguments than were supplied signals only if it is actually selected. - Because
formatexpands statically, a~@[clause must consume exactly the tested argument,#and~@{are not available inside a~{ ... ~}body, and an argument-divergent~[nested inside another composite directive (~(/~{) is not supported. ~:dgrouping and the radix directives~x/~o/~b/~rare exact for integers of any magnitude on every backend.~wprints asprin1and does not read*print-escape*/*print-readably*, so binding one of them around it does not switch it toprinc-- the same gapwrite-to-stringhas (writeitself honors them).
Runtime control strings
A control string that is a runtime value -- a computed control expression, a
call through the function value #'format (funcall/apply), the inner
control of ~?, or a condition's format-control slot -- is rendered by a
runtime renderer instead of being expanded statically. It understands the same
directives as the table above, so the same control string and arguments produce
the same text whichever way format reaches them (on every backend). Two
differences follow from the control being data rather than source:
- The renderer never signals: a malformed control (
"abc~"), an unknown directive (~Q), an unterminated~{, and a missing argument render as text (the directive verbatim,NILfor the missing argument) rather than raising an error. A literal control reports the same problems at expansion time, where a diagnostic belongs; a runtime control usually arrives with the data being reported, and a report must not fail while reporting. - The column-control directive
~t(~n,mT,~n@T), the plural directive~p, the logical-block / justification directive~<...~>and the call-a-function directive~/name/are available here but not in the literal expansion -- a literal control using one falls back to this renderer, so all four work either way.~tmeasures the column from the text rendered so far.
~<...~> is justification and ~<...~:> a logical block; the closing directive
decides which. Their SECTION rules are the standard ones: a justification's ~;
segments consume arguments in turn, while a logical block's first section is the
prefix and, when there are three, the last is the suffix (neither consumes an
argument), and a block without @ takes one argument -- a list -- as its whole
argument list. What does not happen is the LAYOUT: no padding to a minimum
column, no wrapping at the right margin, and of the conditional newlines only the
mandatory ~:@_ breaks a line (~_ / ~:_ / ~@_ and ~i do nothing).
Deciding the others needs the stream's current column, which no rontolisp stream
carries -- the same reason pprint-newline only honors :mandatory.
~/name/ calls the named function as (name stream object colon-p at-p) and
splices what it writes. The name is looked up as if by find-symbol, where a
single and a double colon are equivalent, so ~/mypkg:helper/ reaches an
internal symbol too.
Compiled output carries ~/name/ only when the compiler can see the
directive. Resolving a function out of a control string at run time means any
function in the program can be reached by name, which is exactly what stops the
compiler from removing unused code -- so it includes that part of
the renderer only when some string literal in the program spells a ~/name/
directive (anywhere: the control at the call site, a control bound to a variable,
a control inside a spliced library). That covers every ordinary use. A control
string assembled at run time out of pieces that never spell the directive
signals instead of rendering it, naming the reason; compile with --dynamic to
keep the directive available unconditionally. The interpreter always supports it.
~r without a radix parameter prints the decimal digits; English cardinals and
ordinals are not implemented.
Like the other macros, format is not recognized by the embedded eval runtime
in compiled output (see Compiled eval limitations).