Previous Table of Contents Next


Here is an example of and taken from the code for the function forward-paragraph, which is in the Emacs Lisp source file paragraphs.el.

The forward-paragraph command moves the cursor forward to the end of the current paragraph (this is the outcome we want, yet it is called a side effect).

The and expression is part of the varlist of a let* expression. (A let* expression is like a let expression, except that each element in the varlist is evaluated in sequence, and the values resulting from an earlier evaluation can be used later in the varlist.)

In the function definition for forward-paragraph, a variable called fill- prefix-regexp is given a value if and only if

  A fill-prefix exists10

10A fill-prefix consists of characters at the beginning of a line that are similar for all lines for a paragraph, such as blanks for an indent, or angle brackets for one form of email quotation. The use of a fill-prefix in forward-paragraph means that you can jump to the end of an indented paragraph, or the end of one marked on each line with > or another prefix.
  It is a string of letters
  It should be not be ignored

Later in the function definition, the variable is used in an if expression, and, if it is not nil, the variable is also used to tell the command which lines are part of the paragraph and which are not.

Here is the and expression:

   (and fill-prefix
      (not (equal fill-prefix “”))
      (not paragraph-ignore-fill-prefix)
      (regexp-quote fill-prefix))

Here is what the parts mean:

  fill-prefix—When this variable is evaluated, the value of the fill-prefix, if any, is returned. If there is no fill-prefix, this variable returns nil. This is to check whether there is a fill-prefix.
  (not (equal fill-prefix “”)—This expression checks whether an existing fill-prefix is an empty string, that is, a string with no characters in it. An empty string is not a useful fill-prefix.
  (not paragraph-ignore-fill-prefix)—This expression returns nil if the variable paragraph-ignore-fill-prefix has been turned on by being set to a true value such as t.
  (regexp-quote fill-prefix)—This is the last argument to the and function. If all the arguments to the and are true, the value resulting from evaluating this expression is returned by the and expression and bound to the variable fill-prefix-regexp.

The result of evaluating this and expression successfully is that fill- prefix-regexp is bound to the value of fill-prefix as modified by the regexp-quote function. regexp-quote reads a string and returns a regular expression that exactly matches the string and matches nothing else. This means that fill-prefix-regexp is set to a value that exactly matches the fill-prefix if the fill-prefix exists. Otherwise, the variable is set to nil.

An or expression is often used in a manner that is quite like an if expression. Here, for example, is an extract from the source for the insert-buffer function definition. insert-buffer is a command whose source is found in the simple.el file; the command inserts the contents of a second buffer into the current buffer.

The documentation says

     “Insert after point the contents of BUFFER.
   Puts mark after the inserted text.
   BUFFER may be a buffer or a buffer name.”

The or expression checks whether the argument you pass to insert-buffer, which is the variable buffer, is a buffer or the name of one. (Note that the same symbol, buffer, is being used in two ways in this instance—either as a buffer or as a name. If you are confused by the distinction between a buffer and its name, consider the difference between you personally being introduced to the editor of this volume and your name being mentioned to him. The former is you, the latter is a reference to you.)

The or expression in insert-buffer looks like this:

   (or (bufferp buffer)
      (setq buffer (get-buffer buffer)))

The first argument to or is the expression (bufferp buffer).11 This expression returns true (a non-nil value) if the buffer is actually a buffer, and not just the name of a buffer.


11The p in bufferp stands for predicate. In the jargon used by early Lisp researchers, a predicate refers to a function that determines whether a property is true or false. bufferp determines whether it is true that its argument is a buffer—hence this use of the naming convention.

If the argument is a buffer, the or expression returns this true value and does not evaluate the next expression—and this is fine because the commands do not want to do anything to the value of buffer if it really is a buffer.

On the other hand, if the value of (bufferp buffer) is nil, which it is if the value of buffer is the name of a buffer, the Lisp interpreter evaluates the next element of the or expression. This is the expression:

   (setq buffer (get-buffer buffer))

This expression returns a non-nil value that is the value to which it sets the variable buffer—and this value is a buffer itself, not the name of a buffer.

The result of all this is that the symbol buffer is always bound to a buffer itself rather than to the name of a buffer. All this is necessary because the next part of the code (not shown here) works only with a buffer itself, not with the name of a buffer.

As for or being like if, the expression could have been written like this:

   (if (not (bufferp buffer))
      (setq buffer (get-buffer buffer)))

This would have produced the same result, but is longer and less elegant.

2.13. while Loops and Recursion

Emacs Lisp has two primary ways to cause an expression, or a series of expressions, to be evaluated repeatedly: One uses a while loop, and the other uses recursion.

Repetition is valuable. For example, to move forward four sentences, you need only write a program that moves forward one sentence and then repeats the process an additional three times.

In Emacs Lisp, while loops are used more frequently than recursion because they tend to be faster. (In some other dialects of Lisp, recursion is as fast as or faster than while loops.)


Previous Table of Contents Next