cond vs if in Racket

Short answer

Use if for a single either/or. Use cond for three or more branches — it is flatter and easier to extend than nested ifs.

racket
(if (> score 50) "pass" "fail")

if takes exactly three arguments: the test, the value when true, the value when false. The else branch is mandatory — there is no way to forget it.

#cond for more branches

racket
(define (classify n)
  (cond
    [(< n 0)  "negative"]
    [(= n 0)  "zero"]
    [(< n 10) "small"]
    [else     "large"]))

Clauses are tested in order and the first match wins, so ordering matters — put the narrowest condition first.

Square brackets are interchangeable with parentheses; convention uses them for cond clauses purely to make the structure visible.

#The nested-if version is worse

racket
(if (< n 0)
    "negative"
    (if (= n 0)
        "zero"
        (if (< n 10) "small" "large")))

Same behaviour, four closing parens deep, and adding a branch means restructuring.

#They are expressions, not statements

racket
(define label (if (> n 0) "positive" "non-positive"))

Both return a value. This is the functional mindset — you compose values rather than issue commands.

#Missing else

cond with no matching clause and no else returns void, which usually surfaces as a confusing error later. Always include else.

racket
(when (> n 0) (displayln "positive"))       ; one branch, for side effects
(unless (empty? lst) (process lst))
(case day
  [(sat sun) "weekend"]
  [else "weekday"])

case compares against literal values rather than running tests, so it is faster but less flexible than cond.