Lisp provides a number of conditional constructs, the most complex of
which (cond) will take a list of conditions, the first of which
is t then has its associated list of forms evaluated. Theoretically
this is the only conditional special form necessary -- the rest could
be implemented as macros.
if construct is the nearest thing in Lisp to the if-then-else
construct found in most programming languages.
First the condition form is evaluated, if it returns t (not
nil) the true-form is evaluated and its result returned. Otherwise
the result of an implicit progn on the else-forms is returned. If there
are no else-forms nil is returned.
Note that one of the true-form or the else-forms is completely ignored -- it is not evaluated.
(if (special-form-p 'if)
"`if' is a special form"
"`if' is not a special form")
=> "`if' is a special form"
t the result of an implicit progn
on the true-forms is returned, otherwise nil is returned.
(when t
(message "Pointless")
'foo)
=> foo
nil its value is returned. Otherwise the else-forms are
evaluated sequentially, the value of the last is returned.
cond special form is used to choose between an arbitrary number
of conditions. Each clause is a list; its car is the condition
the list which is the cdr of the clause is the body-forms. This
means that each clause looks something like:
(condition body-forms...)
and a whole cond form looks like:
(cond (condition-1 body-forms-1...) (condition-2 body-forms-2...) ...)
The condition in each clause is evaluated in sequence
(condition-1, then condition-2, ...), the first one
which evaluates to a non-nil has an implicit progn performed on
its body-forms, the value of which is the value returned by the
cond form.
If the true condition has no body-forms the value returned
by cond is the value of the condition. If none of the
clauses has a non-nil condition the value of the cond
is nil.
Often you want a default clause; one which has its body-forms
to be evaluated if none of the other clauses are true. The way to
do this is to add a clause with a condition of t and
body-forms of whatever you want the default action to be.
(cond
((stringp buffer-list)) ;Clause with no body-forms
((consp buffer-list)
(setq x buffer-list) ;Two body-forms
t)
(t ;Default clause
(error "`buffer-list' is corrupted!")))
=> t
All of the other conditionals can be written in terms of cond,
(if c t e...) == (cond (c t) (t e...)) (when c t...) == (cond (c t...)) (unless c e...) == (cond (e) (t e...))
There are also a number of special forms which combine conditions together by the normal logical rules.
nil its value
becomes the value of the or form and no more of forms are
evaluated. Otherwise this step is repeated for the next member of forms.
If all of the forms have been evaluated and none have a non-nil
value nil becomes the value of the or form.
If there are no forms nil is returned.
(or nil 1 nil (beep)) ;(beep) won't be evaluated
=> 1
nil no more
of the forms are evaluated and nil becomes the value of the
and structure. Otherwise the next member of forms is evaluated
and its value tested. If none of the forms are nil the computed
value of the last member of forms becomes the value of the and
form.
(and 1 2 nil (beep)) ;(beep) won't be evaluated
=> nil
(and 1 2 3) ;All forms are evaluated
=> 3
nil, nil is returned, otherwise t is returned.
(not nil)
=> t
(not t)
=> nil
(not 42)
=> nil
Go to the first, previous, next, last section, table of contents.