Skip to content
Lesson 3 of 7

Step 1 of 5 · Reading · ~1 min

Learn

Format and Streams

format is Common Lisp's printf — but on steroids. Hundreds of directives, control flow, conditionals, plurals. Genuinely impressive.

Basic directives:

  • ~a — aesthetic — anything, no quotes
  • ~s — readable — like a, but strings get quotes (s-expression style)
  • ~d — decimal integer
  • ~f — float
  • ~% — newline
  • ~~ — literal tilde
  • ~& — fresh line (newline only if not already at one)

Width and alignment:

(format t "~10a|" "hi")          ;; "hi        |" — left-aligned in a 10-wide field
(format t "~10@a|" "hi")          ;; "        hi|" — @ right-ALIGNS (padding goes on the left)
(format t "~10,,,'.a|" "hi")        ;; "hi........|" — fill with .

Float formatting:

(format t "~,2f" 3.14159)         ;; "3.14"
(format t "~10,2f" 3.14159)        ;; "      3.14"

Plurals:

(format t "~d apple~:p" 1)         ;; "1 apple"
(format t "~d apple~:p" 5)         ;; "5 apples"

Conditional:

(format t "~[zero~;one~;many~]" 0)   ;; "zero"
(format t "~[zero~;one~;many~]" 1)   ;; "one"
(format t "~[zero~;one~:;many~]" 5)   ;; "many" (capped at last)

Iteration over a list:

(format t "~{~a~^, ~}" '(1 2 3 4))
;; "1, 2, 3, 4"
  • ~{ ~} brackets the iteration
  • ~^ exits early (no separator on last item)
  • ~a is the per-item directive

Capitalization:

  • ~( ~) lower-case the contents
  • ~:( capitalize each word
  • ~@( capitalize just the first word

Recursive format with ~?:

(format t "~?" "~d + ~d = ~d" '(2 3 5))

format nil returns the string instead of printing.

format t writes to standard-output.

format stream writes to a specific stream.

When people say Lisp's format is "like a programming language inside printf," they're right. The full directive list is in CLHS chapter 22 — bring tea.

Up nextStreams and File I/OFormat and Streams

Discussion

Ask a question, share an insight, or help someone who’s stuck.

Sign in to post a comment or reply.

Loading…