Formatting
Code layout, indentation, and parenthesis placement.
Indentation
Use 2 spaces for indentation. Never tabs.
(define (factorial n)
(if (zero? n)
1
(* n (factorial (- n 1)))))Parentheses
Never put closing parens on their own line. Stack them at the end.
;; Good
(define (greet name)
(string-append "Hello, " name "!"))
;; Bad
(define (greet name)
(string-append "Hello, " name "!")
)Line Length
Keep lines under 80 characters. Break long expressions sensibly.
;; Too long
(define result (some-function arg1 arg2 arg3 arg4 arg5 arg6 arg7))
;; Better
(define result
(some-function arg1 arg2 arg3
arg4 arg5 arg6
arg7))Function Definitions
Short functions on one line:
(define (square x) (* x x))
(define (add1 x) (+ x 1))Longer functions with body indented:
(define (process-items items)
(filter valid?
(map transform items)))Let Bindings
Align binding values when it improves readability:
(let ((name (get-name user))
(age (get-age user))
(active (user-active? user)))
(format "~a (~a)~a" name age
(if active "" " [inactive]")))Or use simple indentation:
(let ((name (get-name user))
(age (get-age user)))
(process name age))Cond and Case
Align clauses with the opening paren:
(cond
((null? lst) 'empty)
((pair? lst) 'list)
(else 'other))
(case type
((a b c) (handle-abc))
((x y z) (handle-xyz))
(else (handle-default)))Lambda
Short lambdas inline:
(map (lambda (x) (* x 2)) items)
(filter (lambda (x) (> x 0)) numbers)Multi-line lambdas indented:
(map (lambda (item)
(let ((name (item-name item)))
(string-upcase name)))
items)Match
Align patterns with the opening:
(match value
('() "empty")
((x) (format "single: ~a" x))
((x . rest) (format "head: ~a, tail: ~a" x rest)))Blank Lines
One blank line between top-level definitions:
(define (foo x)
...)
(define (bar y)
...)Group related definitions together, separate groups with blank lines:
;; Constructors
(define (make-point x y) ...)
(define (make-rect x y w h) ...)
;; Predicates
(define (point? x) ...)
(define (rect? x) ...)Comments
Align comments with code they describe. Add a blank line before a comment that introduces a new section:
(define (complex-operation x)
;; First, validate input
(validate x)
;; Then process
(process x))End-of-line comments after two spaces:
(define pi 3.14159) ; ApproximationLong Argument Lists
When a call doesn't fit on one line, break after the operator:
(create-user
name: "Alice"
email: "alice@example.com"
role: 'admin
active: #t)Or align with the first argument:
(send-request client
method: 'POST
path: "/api/users"
body: data)