Skip to main content

if

if Special Operator

Syntax:

if test-form then-form [else-form] → {result}*

Arguments and Values:

Test-form—a form.

Then-form—a form.

Else-form—a form. The default is nil.

results—if the test-form yielded true, the values returned by the then-form; otherwise, the values returned by the else-form.

Description:

if allows the execution of a form to be dependent on a single test-form.

First test-form is evaluated. If the result is true, then then-form is selected; otherwise else-form is selected. Whichever form is selected is then evaluated.

Examples:

(if t 1)1 
(if nil 1 2)2
(defun test ()
(dolist (truth-value(t nil 1 (a b c)))
(if truth-value (print ’true) (print ’false))
(prin1 truth-value))) → TEST
(test)
▷ TRUE T
▷ FALSE NIL
▷ TRUE 1
▷ TRUE (A B C)
→ NIL

See Also:

cond, unless, when

Notes:

(if test-form then-form else-form)

(cond (test-form then-form) (t else-form))

Expanded Reference: if

Basic conditional branching

if is the most fundamental conditional form in Common Lisp. It evaluates a test form, then evaluates either the then-form or the else-form depending on the result.

(if t "yes" "no")
=> "yes"

(if nil "yes" "no")
=> "no"

The else-form is optional

When the else-form is omitted and the test is false, if returns NIL.

(if t "true")
=> "true"

(if nil "true")
=> NIL

Any non-NIL value is true

In Common Lisp, every value except NIL is considered true. Numbers, strings, lists, and even the number zero are all true.

(if 0 "zero is true" "zero is false")
=> "zero is true"

(if "" "empty string is true" "empty string is false")
=> "empty string is true"

(if '() "empty list is true" "empty list is false")
=> "empty list is false"

Using if with computed test expressions

The test form can be any expression that returns a value.

(defun check-sign (n)
(if (> n 0)
"positive"
"not positive"))

(check-sign 5)
=> "positive"

(check-sign -3)
=> "not positive"

if only takes a single form per branch

Unlike when or cond, each branch of if is a single form. Use progn to execute multiple forms in a branch.

(let ((x 10))
(if (> x 5)
(progn
(format t "big number~%")
(* x 2))
(progn
(format t "small number~%")
(* x 3))))
.. big number
..
=> 20

Nested if forms

if forms can be nested, though cond is often preferred for readability when there are many branches.

(defun classify (x)
(if (not (numberp x))
"not a number"
(if (< x 0)
"negative"
(if (= x 0)
"zero"
"positive"))))

(classify 42)
=> "positive"
(classify -7)
=> "negative"
(classify 0)
=> "zero"
(classify "hi")
=> "not a number"