Previous Table of Contents Next


2.11. Sequencing

Most commonly, in Emacs Lisp, the Lisp interpreter evaluates expressions in the order in which they appear in the text, that is, left to right, top to bottom. However, inner expressions are evaluated first because the results they produce may be needed by the enclosing expression. Some forms, such as conditionals, evaluate enclosed expressions in uncommon ways.

To ensure that a series of expressions is evaluated in sequence, use the progn special form. Its template looks like this:

   (progn first-expression second-expression ...)

Each expression is evaluated in turn—first, second and so on, in that order. The value of the last expression becomes the value of the entire progn.

progn is often used in the then part of an f expression, because that part can consist of only one list; a subsequent list or lists, if any, belong to the else part.

2.12. Conditionals

Conditionals provide choice. In a conditional, depending on circumstances, one expression or another will be evaluated.

Emacs Lisp has two conditional forms: f and cond (which comes from conditional).

The basic idea behind an f special form is:

if a test is true,
then an expression is evaluated.
or else, if the test is not true,
evaluate a different expression.

The words then and else are not part of the Lisp expression, but you can read the expression as if they were there.

The template is

   (if true-or-false-test
       action-to-carry-out-if-the-test-returns-true)
   action-to-carry-out-if-the-test-returns-false)

For example, in the following, the test determines whether the value of the variable equals the symbol fierce. If it does, Emacs displays the message about the tiger; if not, Emacs displays a message saying “It’s not.”:

   (if (equal characteristic ‘fierce)   ; if part
        (message “It’s a tiger!”)       ; then part
       (message “It’s not.”))           ; else part

Of course, the value of the variable characteristic must be set before the test can occur. An f is part of a larger context.

The second, less frequently used, conditional in Emacs Lisp is cond, which is a generalized case statement.

cond provides a choice among any number of alternatives, only one of which is chosen.

The template for cond looks like this:

   (cond
    ((first-true-or-false-test first-consequent)
     (second-true-or-false-test second-consequent)
     (third-true-or-false-test third-consequent)
    ...)

When a cond expression is evaluated, each test is subject to being evaluated, in textual order. If a test returns a value that is true (that is, any value that is not nil), then the consequent of that test is evaluated. Otherwise, the consequent is not evaluated, but is ignored. After a test returns true and its consequent is evaluated, the remaining tests and consequents are ignored—they are not evaluated. The Lisp interpreter evaluates each test in turn, until one returns true; then it evaluates its consequent and disregards the rest.

Here is an example:

   (cond
    ((equal characteristic ‘fierce)
     (message “It’s a tiger!”))
    ((equal characteristic ‘cuddly)
     (message “It’s a pussy cat!”))
    ((equal characteristic ‘barks)
     (message “It’s a dog!”)))

Suppose you set the value of characteristic to cuddly by evaluating:

   (setq characteristic ‘cuddly)

Then you evaluate the conditional. First the Lisp interpreter tests whether the value of characteristic evaluates to fierce, but that is false, so it ignores the message about the tiger. Then it tests whether the value of characteristic evaluates to cuddly; that is true, so it evaluates the expression saying “It’s a pussy cat!”. The interpreter ignores the test about barking and the expression about the dog.

2.12.1. and, or, and not

and, or, and not are often used together with f and cond to express complicated conditions; they can also be used alone.

When the Lisp interpreter sees and, it evaluates the arguments to and in order. If all the arguments return a value that is true (any non-nil value), then the and expression as a whole returns the value of the last argument. But if any argument is false (returns nil), the interpreter does not evaluate any remaining arguments and returns nil (for false) immediately for the whole expression.

or is, so to speak, the reverse of and. When the Lisp interpreter sees or, it evaluates the arguments to or in order. If any argument returns a true value, then the or expression returns that value and none of the remaining arguments is evaluated. If all the arguments return false, then the or expression returns nil.

not tests whether its argument returns a true value; if so, it returns nil; but if the test returns a nil value, the not expression returns t.


Previous Table of Contents Next