Skip to main content

cond

cond Macro

Syntax:

cond {↓clause}* → {result}*

clause::=(test-form {form}*)

Arguments and Values:

test-form—a form.

forms—an implicit progn.

results—the values of the forms in the first clause whose test-form yields true, or the primary value of the test-form if there are no forms in that clause, or else nil if no test-form yields true.

Description:

cond allows the execution of forms to be dependent on test-form.

Test-forms are evaluated one at a time in the order in which they are given in the argument list until a test-form is found that evaluates to true.

If there are no forms in that clause, the primary value of the test-form is returned by the cond form. Otherwise, the forms associated with this test-form are evaluated in order, left to right, as an implicit progn, and the values returned by the last form are returned by the cond form.

Once one test-form has yielded true, no additional test-forms are evaluated. If no test-form yields true, nil is returned.

Examples:

(defvar a) → a
(defun select-options ()
(cond ((= a 1) (setf a 2))
((= a 2) (setf a 3))
((and (= a 3) (floor a 2)))
(t (floor a 3)))) → SELECT-OPTIONS
(setf a 1)1
(select-options)2
a → 2
(select-options)3
a → 3
(select-options)1
(setf a 5)5
(select-options) → 1, 2

See Also:

if, case.

info

We fixed the examples so that it uses defvar to initialize the variable and to use setf rather than setq for assignment.

Expanded Reference: cond

Basic multi-way conditional

cond evaluates test forms in order. When a test returns true, the corresponding body forms are evaluated and their result is returned. No further clauses are tested.

(defun describe-number (n)
(cond
((< n 0) "negative")
((= n 0) "zero")
(t "positive")))

(describe-number -5)
=> "negative"
(describe-number 0)
=> "zero"
(describe-number 42)
=> "positive"

The t clause as a default

A clause with t as the test form always matches. It is conventionally placed last to act as a default case.

(defun classify-char (ch)
(cond
((alpha-char-p ch) :letter)
((digit-char-p ch) :digit)
(t :other)))

(classify-char #\a)
=> :LETTER
(classify-char #\5)
=> :DIGIT
(classify-char #\!)
=> :OTHER

Returning NIL when no clause matches

If no test form evaluates to true and there is no default clause, cond returns NIL.

(cond
((> 1 2) "impossible")
((< 5 3) "also impossible"))
=> NIL

Clauses with no body forms

When a clause has no body forms, the primary value of the test form itself is returned.

(cond
(nil)
(42)
(t "not reached"))
=> 42

Multiple body forms in a clause

Each clause supports multiple body forms (an implicit progn). All forms are evaluated and the last value is returned.

(let ((x 10))
(cond
((> x 100)
(format t "Very large~%")
:very-large)
((> x 5)
(format t "Moderate~%")
:moderate)
(t
(format t "Small~%")
:small)))
.. Moderate
..
=> :MODERATE

Using cond to implement FizzBuzz

A practical example showing cond with compound test expressions.

(defun fizzbuzz (n)
(cond
((zerop (mod n 15)) "FizzBuzz")
((zerop (mod n 3)) "Fizz")
((zerop (mod n 5)) "Buzz")
(t n)))

(fizzbuzz 3)
=> "Fizz"
(fizzbuzz 5)
=> "Buzz"
(fizzbuzz 15)
=> "FizzBuzz"
(fizzbuzz 7)
=> 7