[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

3. How To Write Function Definitions

When the Lisp interpreter evaluates a list, it looks to see whether the first symbol on the list has a function definition attached to it; or, put another way, whether the symbol points to a function definition. If it does, the computer carries out the instructions in the definition. A symbol that has a function definition is called, simply, a function (although, properly speaking, the definition is the function and the symbol refers to it.)

An Aside about Primitive Functions  
3.1 The defun Special Form  The defun special form.
3.2 Install a Function Definition  Install a function definition.
3.3 Make a Function Interactive  Making a function interactive.
3.4 Different Options for interactive  Different options for interactive.
3.5 Install Code Permanently  Installing code permanently.
3.6 let  Creating and initializing local variables.
3.7 The if Special Form  What if?
3.8 If--then--else Expressions  If--then--else expressions.
3.9 Truth and Falsehood in Emacs Lisp  What Lisp considers false and true.
3.10 save-excursion  Keeping track of point, mark, and buffer.
3.11 Review  
3.12 Exercises  


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

An Aside about Primitive Functions

All functions are defined in terms of other functions, except for a few primitive functions that are written in the C programming language. When you write functions' definitions, you will write them in Emacs Lisp and use other functions as your building blocks. Some of the functions you will use will themselves be written in Emacs Lisp (perhaps by you) and some will be primitives written in C. The primitive functions are used exactly like those written in Emacs Lisp and behave like them. They are written in C so we can easily run GNU Emacs on any computer that has sufficient power and can run C.

Let me re-emphasize this: when you write code in Emacs Lisp, you do not distinguish between the use of functions written in C and the use of functions written in Emacs Lisp. The difference is irrelevant. I mention the distinction only because it is interesting to know. Indeed, unless you investigate, you won't know whether an already-written function is written in Emacs Lisp or C.


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

3.1 The defun Special Form

In Lisp, a symbol such as mark-whole-buffer has code attached to it that tells the computer what to do when the function is called. This code is called the function definition and is created by evaluating a Lisp expression that starts with the symbol defun (which is an abbreviation for define function). Because defun does not evaluate its arguments in the usual way, it is called a special form.

In subsequent sections, we will look at function definitions from the Emacs source code, such as mark-whole-buffer. In this section, we will describe a simple function definition so you can see how it looks. This function definition uses arithmetic because it makes for a simple example. Some people dislike examples using arithmetic; however, if you are such a person, do not despair. Hardly any of the code we will study in the remainder of this introduction involves arithmetic or mathematics. The examples mostly involve text in one way or another.

A function definition has up to five parts following the word defun:

  1. The name of the symbol to which the function definition should be attached.

  2. A list of the arguments that will be passed to the function. If no arguments will be passed to the function, this is an empty list, ().

  3. Documentation describing the function. (Technically optional, but strongly recommended.)

  4. Optionally, an expression to make the function interactive so you can use it by typing M-x and then the name of the function; or by typing an appropriate key or keychord.

  5. The code that instructs the computer what to do: the body of the function definition.

It is helpful to think of the five parts of a function definition as being organized in a template, with slots for each part:

 
(defun function-name (arguments...)
  "optional-documentation..."
  (interactive argument-passing-info)     ; optional
  body...)

As an example, here is the code for a function that multiplies its argument by 7. (This example is not interactive. See section Making a Function Interactive, for that information.)

 
(defun multiply-by-seven (number)
  "Multiply NUMBER by seven."
  (* 7 number))

This definition begins with a parenthesis and the symbol defun, followed by the name of the function.

The name of the function is followed by a list that contains the arguments that will be passed to the function. This list is called the argument list. In this example, the list has only one element, the symbol, number. When the function is used, the symbol will be bound to the value that is used as the argument to the function.

Instead of choosing the word number for the name of the argument, I could have picked any other name. For example, I could have chosen the word multiplicand. I picked the word `number' because it tells what kind of value is intended for this slot; but I could just as well have chosen the word `multiplicand' to indicate the role that the value placed in this slot will play in the workings of the function. I could have called it foogle, but that would have been a bad choice because it would not tell humans what it means. The choice of name is up to the programmer and should be chosen to make the meaning of the function clear.

Indeed, you can choose any name you wish for a symbol in an argument list, even the name of a symbol used in some other function: the name you use in an argument list is private to that particular definition. In that definition, the name refers to a different entity than any use of the same name outside the function definition. Suppose you have a nick-name `Shorty' in your family; when your family members refer to `Shorty', they mean you. But outside your family, in a movie, for example, the name `Shorty' refers to someone else. Because a name in an argument list is private to the function definition, you can change the value of such a symbol inside the body of a function without changing its value outside the function. The effect is similar to that produced by a let expression. (See section let.)

The argument list is followed by the documentation string that describes the function. This is what you see when you type C-h f and the name of a function. Incidentally, when you write a documentation string like this, you should make the first line a complete sentence since some commands, such as apropos, print only the first line of a multi-line documentation string. Also, you should not indent the second line of a documentation string, if you have one, because that looks odd when you use C-h f (describe-function). The documentation string is optional, but it is so useful, it should be included in almost every function you write.

The third line of the example consists of the body of the function definition. (Most functions' definitions, of course, are longer than this.) In this function, the body is the list, (* 7 number), which says to multiply the value of number by 7. (In Emacs Lisp, * is the function for multiplication, just as + is the function for addition.)

When you use the multiply-by-seven function, the argument number evaluates to the actual number you want used. Here is an example that shows how multiply-by-seven is used; but don't try to evaluate this yet!

 
(multiply-by-seven 3)

The symbol number, specified in the function definition in the next section, is given or "bound to" the value 3 in the actual use of the function. Note that although number was inside parentheses in the function definition, the argument passed to the multiply-by-seven function is not in parentheses. The parentheses are written in the function definition so the computer can figure out where the argument list ends and the rest of the function definition begins.

If you evaluate this example, you are likely to get an error message. (Go ahead, try it!) This is because we have written the function definition, but not yet told the computer about the definition--we have not yet installed (or `loaded') the function definition in Emacs. Installing a function is the process that tells the Lisp interpreter the definition of the function. Installation is described in the next section.


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

3.2 Install a Function Definition

If you are reading this inside of Info in Emacs, you can try out the multiply-by-seven function by first evaluating the function definition and then evaluating (multiply-by-seven 3). A copy of the function definition follows. Place the cursor after the last parenthesis of the function definition and type C-x C-e. When you do this, multiply-by-seven will appear in the echo area. (What this means is that when a function definition is evaluated, the value it returns is the name of the defined function.) At the same time, this action installs the function definition.

 
(defun multiply-by-seven (number)
  "Multiply NUMBER by seven."
  (* 7 number))

By evaluating this defun, you have just installed multiply-by-seven in Emacs. The function is now just as much a part of Emacs as forward-word or any other editing function you use. (multiply-by-seven will stay installed until you quit Emacs. To reload code automatically whenever you start Emacs, see Installing Code Permanently.)

The effect of installation  
3.2.1 Change a Function Definition  How to change a function definition.


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

The effect of installation

You can see the effect of installing multiply-by-seven by evaluating the following sample. Place the cursor after the following expression and type C-x C-e. The number 21 will appear in the echo area.

 
(multiply-by-seven 3)

If you wish, you can read the documentation for the function by typing C-h f (describe-function) and then the name of the function, multiply-by-seven. When you do this, a `*Help*' window will appear on your screen that says:

 
multiply-by-seven:
Multiply NUMBER by seven.

(To return to a single window on your screen, type C-x 1.)


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

3.2.1 Change a Function Definition

If you want to change the code in multiply-by-seven, just rewrite it. To install the new version in place of the old one, evaluate the function definition again. This is how you modify code in Emacs. It is very simple.

As an example, you can change the multiply-by-seven function to add the number to itself seven times instead of multiplying the number by seven. It produces the same answer, but by a different path. At the same time, we will add a comment to the code; a comment is text that the Lisp interpreter ignores, but that a human reader may find useful or enlightening. The comment is that this is the "second version".

 
(defun multiply-by-seven (number)       ; Second version.
  "Multiply NUMBER by seven."
  (+ number number number number number number number))

The comment follows a semicolon, `;'. In Lisp, everything on a line that follows a semicolon is a comment. The end of the line is the end of the comment. To stretch a comment over two or more lines, begin each line with a semicolon.

See section Beginning a `.emacs' File, and section `Comments' in The GNU Emacs Lisp Reference Manual, for more about comments.

You can install this version of the multiply-by-seven function by evaluating it in the same way you evaluated the first function: place the cursor after the last parenthesis and type C-x C-e.

In summary, this is how you write code in Emacs Lisp: you write a function; install it; test it; and then make fixes or enhancements and install it again.


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

3.3 Make a Function Interactive

You make a function interactive by placing a list that begins with the special form interactive immediately after the documentation. A user can invoke an interactive function by typing M-x and then the name of the function; or by typing the keys to which it is bound, for example, by typing C-n for next-line or C-x h for mark-whole-buffer.

Interestingly, when you call an interactive function interactively, the value returned is not automatically displayed in the echo area. This is because you often call an interactive function for its side effects, such as moving forward by a word or line, and not for the value returned. If the returned value were displayed in the echo area each time you typed a key, it would be very distracting.

An Interactive multiply-by-seven, An Overview  An overview.
3.3.1 An Interactive multiply-by-seven  The interactive version.


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

An Interactive multiply-by-seven, An Overview

Both the use of the special form interactive and one way to display a value in the echo area can be illustrated by creating an interactive version of multiply-by-seven.

Here is the code:

 
(defun multiply-by-seven (number)       ; Interactive version.
  "Multiply NUMBER by seven."
  (interactive "p")
  (message "The result is %d" (* 7 number)))

You can install this code by placing your cursor after it and typing C-x C-e. The name of the function will appear in your echo area. Then, you can use this code by typing C-u and a number and then typing M-x multiply-by-seven and pressing RET. The phrase `The result is ...' followed by the product will appear in the echo area.

Speaking more generally, you invoke a function like this in either of two ways:

  1. By typing a prefix argument that contains the number to be passed, and then typing M-x and the name of the function, as with C-u 3 M-x forward-sentence; or,

  2. By typing whatever key or keychord the function is bound to, as with C-u 3 M-e.

Both the examples just mentioned work identically to move point forward three sentences. (Since multiply-by-seven is not bound to a key, it could not be used as an example of key binding.)

(See section Some Keybindings, to learn how to bind a command to a key.)

A prefix argument is passed to an interactive function by typing the META key followed by a number, for example, M-3 M-e, or by typing C-u and then a number, for example, C-u 3 M-e (if you type C-u without a number, it defaults to 4).


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

3.3.1 An Interactive multiply-by-seven

Let's look at the use of the special form interactive and then at the function message in the interactive version of multiply-by-seven. You will recall that the function definition looks like this:

 
(defun multiply-by-seven (number)       ; Interactive version.
  "Multiply NUMBER by seven."
  (interactive "p")
  (message "The result is %d" (* 7 number)))

In this function, the expression, (interactive "p"), is a list of two elements. The "p" tells Emacs to pass the prefix argument to the function and use its value for the argument of the function.

The argument will be a number. This means that the symbol number will be bound to a number in the line:

 
(message "The result is %d" (* 7 number))

For example, if your prefix argument is 5, the Lisp interpreter will evaluate the line as if it were:

 
(message "The result is %d" (* 7 5))

(If you are reading this in GNU Emacs, you can evaluate this expression yourself.) First, the interpreter will evaluate the inner list, which is (* 7 5). This returns a value of 35. Next, it will evaluate the outer list, passing the values of the second and subsequent elements of the list to the function message.

As we have seen, message is an Emacs Lisp function especially designed for sending a one line message to a user. (See section The message function.) In summary, the message function prints its first argument in the echo area as is, except for occurrences of `%d', `%s', or `%c'. When it sees one of these control sequences, the function looks to the second and subsequent arguments and prints the value of the argument in the location in the string where the control sequence is located.

In the interactive multiply-by-seven function, the control string is `%d', which requires a number, and the value returned by evaluating (* 7 5) is the number 35. Consequently, the number 35 is printed in place of the `%d' and the message is `The result is 35'.

(Note that when you call the function multiply-by-seven, the message is printed without quotes, but when you call message, the text is printed in double quotes. This is because the value returned by message is what appears in the echo area when you evaluate an expression whose first element is message; but when embedded in a function, message prints the text as a side effect without quotes.)


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

3.4 Different Options for interactive

In the example, multiply-by-seven used "p" as the argument to interactive. This argument told Emacs to interpret your typing either C-u followed by a number or META followed by a number as a command to pass that number to the function as its argument. Emacs has more than twenty characters predefined for use with interactive. In almost every case, one of these options will enable you to pass the right information interactively to a function. (See section `Code Characters for interactive' in The GNU Emacs Lisp Reference Manual.)

For example, the character `r' causes Emacs to pass the beginning and end of the region (the current values of point and mark) to the function as two separate arguments. It is used as follows:

 
(interactive "r")

On the other hand, a `B' tells Emacs to ask for the name of a buffer that will be passed to the function. When it sees a `B', Emacs will ask for the name by prompting the user in the minibuffer, using a string that follows the `B', as in "BAppend to buffer: ". Not only will Emacs prompt for the name, but Emacs will complete the name if you type enough of it and press TAB.

A function with two or more arguments can have information passed to each argument by adding parts to the string that follows interactive. When you do this, the information is passed to each argument in the same order it is specified in the interactive list. In the string, each part is separated from the next part by a `\n', which is a newline. For example, you could follow "BAppend to buffer: " with a `\n') and an `r'. This would cause Emacs to pass the values of point and mark to the function as well as prompt you for the buffer--three arguments in all.

In this case, the function definition would look like the following, where buffer, start, and end are the symbols to which interactive binds the buffer and the current values of the beginning and ending of the region:

 
(defun name-of-function (buffer start end)
  "documentation..."
  (interactive "BAppend to buffer: \nr")
  body-of-function...)

(The space after the colon in the prompt makes it look better when you are prompted. The append-to-buffer function looks exactly like this. See section The Definition of append-to-buffer.)

If a function does not have arguments, then interactive does not require any. Such a function contains the simple expression (interactive). The mark-whole-buffer function is like this.

Alternatively, if the special letter-codes are not right for your application, you can pass your own arguments to interactive as a list. See section `Using Interactive' in The GNU Emacs Lisp Reference Manual, for more information about this advanced technique.


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

3.5 Install Code Permanently

When you install a function definition by evaluating it, it will stay installed until you quit Emacs. The next time you start a new session of Emacs, the function will not be installed unless you evaluate the function definition again.

At some point, you may want to have code installed automatically whenever you start a new session of Emacs. There are several ways of doing this:

Finally, if you have code that everyone who uses Emacs may want, you can post it on a computer network or send a copy to the Free Software Foundation. (When you do this, please license the code and its documentation under a license that permits other people to run, copy, study, modify, and redistribute the code and which protects you from having your work taken from you.) If you send a copy of your code to the Free Software Foundation, and properly protect yourself and others, it may be included in the next release of Emacs. In large part, this is how Emacs has grown over the past years, by donations.


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

3.6 let

The let expression is a special form in Lisp that you will need to use in most function definitions.

let is used to attach or bind a symbol to a value in such a way that the Lisp interpreter will not confuse the variable with a variable of the same name that is not part of the function.

To understand why the let special form is necessary, consider the situation in which you own a home that you generally refer to as `the house', as in the sentence, "The house needs painting." If you are visiting a friend and your host refers to `the house', he is likely to be referring to his house, not yours, that is, to a different house.

If your friend is referring to his house and you think he is referring to your house, you may be in for some confusion. The same thing could happen in Lisp if a variable that is used inside of one function has the same name as a variable that is used inside of another function, and the two are not intended to refer to the same value. The let special form prevents this kind of confusion.

let Prevents Confusion  
3.6.1 The Parts of a let Expression  
3.6.2 Sample let Expression  
3.6.3 Uninitialized Variables in a let Statement  


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

let Prevents Confusion

The let special form prevents confusion. let creates a name for a local variable that overshadows any use of the same name outside the let expression. This is like understanding that whenever your host refers to `the house', he means his house, not yours. (Symbols used in argument lists work the same way. See section The defun Special Form.)

Local variables created by a let expression retain their value only within the let expression itself (and within expressions called within the let expression); the local variables have no effect outside the let expression.

Another way to think about let is that it is like a setq that is temporary and local. The values set by let are automatically undone when the let is finished. The setting only effects expressions that are inside the bounds of the let expression. In computer science jargon, we would say "the binding of a symbol is visible only in functions called in the let form; in Emacs Lisp, scoping is dynamic, not lexical."

let can create more than one variable at once. Also, let gives each variable it creates an initial value, either a value specified by you, or nil. (In the jargon, this is called `binding the variable to the value'.) After let has created and bound the variables, it executes the code in the body of the let, and returns the value of the last expression in the body, as the value of the whole let expression. (`Execute' is a jargon term that means to evaluate a list; it comes from the use of the word meaning `to give practical effect to' (Oxford English Dictionary). Since you evaluate an expression to perform an action, `execute' has evolved as a synonym to `evaluate'.)


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

3.6.1 The Parts of a let Expression

A let expression is a list of three parts. The first part is the symbol let. The second part is a list, called a varlist, each element of which is either a symbol by itself or a two-element list, the first element of which is a symbol. The third part of the let expression is the body of the let. The body usually consists of one or more lists.

A template for a let expression looks like this:

 
(let varlist body...)

The symbols in the varlist are the variables that are given initial values by the let special form. Symbols by themselves are given the initial value of nil; and each symbol that is the first element of a two-element list is bound to the value that is returned when the Lisp interpreter evaluates the second element.

Thus, a varlist might look like this: (thread (needles 3)). In this case, in a let expression, Emacs binds the symbol thread to an initial value of nil, and binds the symbol needles to an initial value of 3.

When you write a let expression, what you do is put the appropriate expressions in the slots of the let expression template.

If the varlist is composed of two-element lists, as is often the case, the template for the let expression looks like this:

 
(let ((variable value)
      (variable value)
      ...)
  body...)


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

3.6.2 Sample let Expression

The following expression creates and gives initial values to the two variables zebra and tiger. The body of the let expression is a list which calls the message function.

 
(let ((zebra 'stripes)
      (tiger 'fierce))
  (message "One kind of animal has %s and another is %s."
           zebra tiger))

Here, the varlist is ((zebra 'stripes) (tiger 'fierce)).

The two variables are zebra and tiger. Each variable is the first element of a two-element list and each value is the second element of its two-element list. In the varlist, Emacs binds the variable zebra to the value stripes, and binds the variable tiger to the value fierce. In this example, both values are symbols preceded by a quote. The values could just as well have been another list or a string. The body of the let follows after the list holding the variables. In this example, the body is a list that uses the message function to print a string in the echo area.

You may evaluate the example in the usual fashion, by placing the cursor after the last parenthesis and typing C-x C-e. When you do this, the following will appear in the echo area:

 
"One kind of animal has stripes and another is fierce."

As we have seen before, the message function prints its first argument, except for `%s'. In this example, the value of the variable zebra is printed at the location of the first `%s' and the value of the variable tiger is printed at the location of the second `%s'.


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

3.6.3 Uninitialized Variables in a let Statement

If you do not bind the variables in a let statement to specific initial values, they will automatically be bound to an initial value of nil, as in the following expression:

 
(let ((birch 3)
      pine
      fir
      (oak 'some))
  (message
   "Here are %d variables with %s, %s, and %s value."
   birch pine fir oak))

Here, the varlist is ((birch 3) pine fir (oak 'some)).

If you evaluate this expression in the usual way, the following will appear in your echo area:

 
"Here are 3 variables with nil, nil, and some value."

In this example, Emacs binds the symbol birch to the number 3, binds the symbols pine and fir to nil, and binds the symbol oak to the value some.

Note that in the first part of the let, the variables pine and fir stand alone as atoms that are not surrounded by parentheses; this is because they are being bound to nil, the empty list. But oak is bound to some and so is a part of the list (oak 'some). Similarly, birch is bound to the number 3 and so is in a list with that number. (Since a number evaluates to itself, the number does not need to be quoted. Also, the number is printed in the message using a `%d' rather than a `%s'.) The four variables as a group are put into a list to delimit them from the body of the let.


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

3.7 The if Special Form

A third special form, in addition to defun and let, is the conditional if. This form is used to instruct the computer to make decisions. You can write function definitions without using if, but it is used often enough, and is important enough, to be included here. It is used, for example, in the code for the function beginning-of-buffer.

The basic idea behind an if, is that "if a test is true, then an expression is evaluated." If the test is not true, the expression is not evaluated. For example, you might make a decision such as, "if it is warm and sunny, then go to the beach!"

if in more detail  
3.7.1 The type-of-animal Function in Detail  An example of an if expression.


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

if in more detail

An if expression written in Lisp does not use the word `then'; the test and the action are the second and third elements of the list whose first element is if. Nonetheless, the test part of an if expression is often called the if-part and the second argument is often called the then-part.

Also, when an if expression is written, the true-or-false-test is usually written on the same line as the symbol if, but the action to carry out if the test is true, the "then-part", is written on the second and subsequent lines. This makes the if expression easier to read.

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

The true-or-false-test will be an expression that is evaluated by the Lisp interpreter.

Here is an example that you can evaluate in the usual manner. The test is whether the number 5 is greater than the number 4. Since it is, the message `5 is greater than 4!' will be printed.

 
(if (> 5 4)                             ; if-part
    (message "5 is greater than 4!"))   ; then-part

(The function > tests whether its first argument is greater than its second argument and returns true if it is.)

Of course, in actual use, the test in an if expression will not be fixed for all time as it is by the expression (> 5 4). Instead, at least one of the variables used in the test will be bound to a value that is not known ahead of time. (If the value were known ahead of time, we would not need to run the test!)

For example, the value may be bound to an argument of a function definition. In the following function definition, the character of the animal is a value that is passed to the function. If the value bound to characteristic is fierce, then the message, `It's a tiger!' will be printed; otherwise, nil will be returned.

 
(defun type-of-animal (characteristic)
  "Print message in echo area depending on CHARACTERISTIC.
If the CHARACTERISTIC is the symbol `fierce',
then warn of a tiger."
  (if (equal characteristic 'fierce)
      (message "It's a tiger!")))

If you are reading this inside of GNU Emacs, you can evaluate the function definition in the usual way to install it in Emacs, and then you can evaluate the following two expressions to see the results:

 
(type-of-animal 'fierce)

(type-of-animal 'zebra)

When you evaluate (type-of-animal 'fierce), you will see the following message printed in the echo area: "It's a tiger!"; and when you evaluate (type-of-animal 'zebra) you will see nil printed in the echo area.


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

3.7.1 The type-of-animal Function in Detail

Let's look at the type-of-animal function in detail.

The function definition for type-of-animal was written by filling the slots of two templates, one for a function definition as a whole, and a second for an if expression.

The template for every function that is not interactive is:

 
(defun name-of-function (argument-list)
  "documentation..."
  body...)

The parts of the function that match this template look like this:

 
(defun type-of-animal (characteristic)
  "Print message in echo area depending on CHARACTERISTIC.
If the CHARACTERISTIC is the symbol `fierce',
then warn of a tiger."
  body: the if expression)

The name of function is type-of-animal; it is passed the value of one argument. The argument list is followed by a multi-line documentation string. The documentation string is included in the example because it is a good habit to write documentation string for every function definition. The body of the function definition consists of the if expression.

The template for an if expression looks like this:

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

In the type-of-animal function, the code for the if looks like this:

 
(if (equal characteristic 'fierce)
    (message "It's a tiger!")))

Here, the true-or-false-test is the expression:

 
(equal characteristic 'fierce)

In Lisp, equal is a function that determines whether its first argument is equal to its second argument. The second argument is the quoted symbol 'fierce and the first argument is the value of the symbol characteristic---in other words, the argument passed to this function.

In the first exercise of type-of-animal, the argument fierce is passed to type-of-animal. Since fierce is equal to fierce, the expression, (equal characteristic 'fierce), returns a value of true. When this happens, the if evaluates the second argument or then-part of the if: (message "It's tiger!").

On the other hand, in the second exercise of type-of-animal, the argument zebra is passed to type-of-animal. zebra is not equal to fierce, so the then-part is not evaluated and nil is returned by the if expression.


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

3.8 If--then--else Expressions

An if expression may have an optional third argument, called the else-part, for the case when the true-or-false-test returns false. When this happens, the second argument or then-part of the overall if expression is not evaluated, but the third or else-part is evaluated. You might think of this as the cloudy day alternative for the decision `if it is warm and sunny, then go to the beach, else read a book!".

The word "else" is not written in the Lisp code; the else-part of an if expression comes after the then-part. In the written Lisp, the else-part is usually written to start on a line of its own and is indented less than the then-part:

 
(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, the following if expression prints the message `4 is not greater than 5!' when you evaluate it in the usual way:

 
(if (> 4 5)                             ; if-part
    (message "5 is greater than 4!")    ; then-part
  (message "4 is not greater than 5!")) ; else-part

Note that the different levels of indentation make it easy to distinguish the then-part from the else-part. (GNU Emacs has several commands that automatically indent if expressions correctly. See section GNU Emacs Helps You Type Lists.)

We can extend the type-of-animal function to include an else-part by simply incorporating an additional part to the if expression.

You can see the consequences of doing this if you evaluate the following version of the type-of-animal function definition to install it and then evaluate the two subsequent expressions to pass different arguments to the function.

 
(defun type-of-animal (characteristic)  ; Second version.
  "Print message in echo area depending on CHARACTERISTIC.
If the CHARACTERISTIC is the symbol `fierce',
then warn of a tiger;
else say it's not fierce."
  (if (equal characteristic 'fierce)
      (message "It's a tiger!")
    (message "It's not fierce!")))

 
(type-of-animal 'fierce)

(type-of-animal 'zebra)

When you evaluate (type-of-animal 'fierce), you will see the following message printed in the echo area: "It's a tiger!"; but when you evaluate (type-of-animal 'zebra), you will see "It's not fierce!".

(Of course, if the characteristic were ferocious, the message "It's not fierce!" would be printed; and it would be misleading! When you write code, you need to take into account the possibility that some such argument will be tested by the if and write your program accordingly.)


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

3.9 Truth and Falsehood in Emacs Lisp

There is an important aspect to the truth test in an if expression. So far, we have spoken of `true' and `false' as values of predicates as if they were new kinds of Emacs Lisp objects. In fact, `false' is just our old friend nil. Anything else--anything at all--is `true'.

The expression that tests for truth is interpreted as true if the result of evaluating it is a value that is not nil. In other words, the result of the test is considered true if the value returned is a number such as 47, a string such as "hello", or a symbol (other than nil) such as flowers, or a list, or even a buffer!

An explanation of nil  nil has two meanings.


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

An explanation of nil

Before illustrating a test for truth, we need an explanation of nil.

In Emacs Lisp, the symbol nil has two meanings. First, it means the empty list. Second, it means false and is the value returned when a true-or-false-test tests false. nil can be written as an empty list, (), or as nil. As far as the Lisp interpreter is concerned, () and nil are the same. Humans, however, tend to use nil for false and () for the empty list.

In Emacs Lisp, any value that is not nil---is not the empty list--is considered true. This means that if an evaluation returns something that is not an empty list, an if expression will test true. For example, if a number is put in the slot for the test, it will be evaluated and will return itself, since that is what numbers do when evaluated. In this conditional, the if expression will test true. The expression tests false only when nil, an empty list, is returned by evaluating the expression.

You can see this by evaluating the two expressions in the following examples.

In the first example, the number 4 is evaluated as the test in the if expression and returns itself; consequently, the then-part of the expression is evaluated and returned: `true' appears in the echo area. In the second example, the nil indicates false; consequently, the else-part of the expression is evaluated and returned: `false' appears in the echo area.

 
(if 4
    'true
  'false)

(if nil
    'true
  'false)

Incidentally, if some other useful value is not available for a test that returns true, then the Lisp interpreter will return the symbol t for true. For example, the expression (> 5 4) returns t when evaluated, as you can see by evaluating it in the usual way:

 
(> 5 4)

On the other hand, this function returns nil if the test is false.

 
(> 4 5)


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

3.10 save-excursion

The save-excursion function is the fourth and final special form that we will discuss in this chapter.

In Emacs Lisp programs used for editing, the save-excursion function is very common. It saves the location of point and mark, executes the body of the function, and then restores point and mark to their previous positions if their locations were changed. Its primary purpose is to keep the user from being surprised and disturbed by unexpected movement of point or mark.

Point and Mark  A review of various locations.
3.10.1 Template for a save-excursion Expression  


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

Point and Mark

Before discussing save-excursion, however, it may be useful first to review what point and mark are in GNU Emacs. Point is the current location of the cursor. Wherever the cursor is, that is point. More precisely, on terminals where the cursor appears to be on top of a character, point is immediately before the character. In Emacs Lisp, point is an integer. The first character in a buffer is number one, the second is number two, and so on. The function point returns the current position of the cursor as a number. Each buffer has its own value for point.

The mark is another position in the buffer; its value can be set with a command such as C-SPC (set-mark-command). If a mark has been set, you can use the command C-x C-x (exchange-point-and-mark) to cause the cursor to jump to the mark and set the mark to be the previous position of point. In addition, if you set another mark, the position of the previous mark is saved in the mark ring. Many mark positions can be saved this way. You can jump the cursor to a saved mark by typing C-u C-SPC one or more times.

The part of the buffer between point and mark is called the region. Numerous commands work on the region, including center-region, count-lines-region, kill-region, and print-region.

The save-excursion special form saves the locations of point and mark and restores those positions after the code within the body of the special form is evaluated by the Lisp interpreter. Thus, if point were in the beginning of a piece of text and some code moved point to the end of the buffer, the save-excursion would put point back to where it was before, after the expressions in the body of the function were evaluated.

In Emacs, a function frequently moves point as part of its internal workings even though a user would not expect this. For example, count-lines-region moves point. To prevent the user from being bothered by jumps that are both unexpected and (from the user's point of view) unnecessary, save-excursion is often used to keep point and mark in the location expected by the user. The use of save-excursion is good housekeeping.

To make sure the house stays clean, save-excursion restores the values of point and mark even if something goes wrong in the code inside of it (or, to be more precise and to use the proper jargon, "in case of abnormal exit"). This feature is very helpful.

In addition to recording the values of point and mark, save-excursion keeps track of the current buffer, and restores it, too. This means you can write code that will change the buffer and have save-excursion switch you back to the original buffer. This is how save-excursion is used in append-to-buffer. (See section The Definition of append-to-buffer.)


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

3.10.1 Template for a save-excursion Expression

The template for code using save-excursion is simple:

 
(save-excursion
  body...)

The body of the function is one or more expressions that will be evaluated in sequence by the Lisp interpreter. If there is more than one expression in the body, the value of the last one will be returned as the value of the save-excursion function. The other expressions in the body are evaluated only for their side effects; and save-excursion itself is used only for its side effect (which is restoring the positions of point and mark).

In more detail, the template for a save-excursion expression looks like this:

 
(save-excursion
  first-expression-in-body
  second-expression-in-body
  third-expression-in-body
   ...
  last-expression-in-body)

An expression, of course, may be a symbol on its own or a list.

In Emacs Lisp code, a save-excursion expression often occurs within the body of a let expression. It looks like this:

 
(let varlist
  (save-excursion
    body...))


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

3.11 Review

In the last few chapters we have introduced a fair number of functions and special forms. Here they are described in brief, along with a few similar functions that have not been mentioned yet.

eval-last-sexp
Evaluate the last symbolic expression before the current location of point. The value is printed in the echo area unless the function is invoked with an argument; in that case, the output is printed in the current buffer. This command is normally bound to C-x C-e.

defun
Define function. This special form has up to five parts: the name, a template for the arguments that will be passed to the function, documentation, an optional interactive declaration, and the body of the definition.

For example:

 
(defun back-to-indentation ()
  "Move point to first visible character on line."
  (interactive)
  (beginning-of-line 1)
  (skip-chars-forward " \t"))

interactive
Declare to the interpreter that the function can be used interactively. This special form may be followed by a string with one or more parts that pass the information to the arguments of the function, in sequence. These parts may also tell the interpreter to prompt for information. Parts of the string are separated by newlines, `\n'.

Common code characters are:

b
The name of an existing buffer.

f
The name of an existing file.

p
The numeric prefix argument. (Note that this `p' is lower case.)

r
Point and the mark, as two numeric arguments, smallest first. This is the only code letter that specifies two successive arguments rather than one.

See section `Code Characters for `interactive'' in The GNU Emacs Lisp Reference Manual, for a complete list of code characters.

let
Declare that a list of variables is for use within the body of the let and give them an initial value, either nil or a specified value; then evaluate the rest of the expressions in the body of the let and return the value of the last one. Inside the body of the let, the Lisp interpreter does not see the values of the variables of the same names that are bound outside of the let.

For example,

 
(let ((foo (buffer-name))
      (bar (buffer-size)))
  (message
   "This buffer is %s and has %d characters."
   foo bar))

save-excursion
Record the values of point and mark and the current buffer before evaluating the body of this special form. Restore the values of point and mark and buffer afterward.

For example,

 
(message "We are %d characters into this buffer."
         (- (point)
            (save-excursion
              (goto-char (point-min)) (point))))

if
Evaluate the first argument to the function; if it is true, evaluate the second argument; else evaluate the third argument, if there is one.

The if special form is called a conditional. There are other conditionals in Emacs Lisp, but if is perhaps the most commonly used.

For example,

 
(if (string-equal
     (number-to-string 21)
     (substring (emacs-version) 10 12))
    (message "This is version 21 Emacs")
  (message "This is not version 21 Emacs"))

equal
eq
Test whether two objects are the same. equal uses one meaning of the word `same' and eq uses another: equal returns true if the two objects have a similar structure and contents, such as two copies of the same book. On the other hand, eq, returns true if both arguments are actually the same object.

<
>
<=
>=
The < function tests whether its first argument is smaller than its second argument. A corresponding function, >, tests whether the first argument is greater than the second. Likewise, <= tests whether the first argument is less than or equal to the second and >= tests whether the first argument is greater than or equal to the second. In all cases, both arguments must be numbers or markers (markers indicate positions in buffers).

string<
string-lessp
string=
string-equal
The string-lessp function tests whether its first argument is smaller than the second argument. A shorter, alternative name for the same function (a defalias) is string<.

The arguments to string-lessp must be strings or symbols; the ordering is lexicographic, so case is significant. The print names of symbols are used instead of the symbols themselves.

An empty string, `""', a string with no characters in it, is smaller than any string of characters.

string-equal provides the corresponding test for equality. Its shorter, alternative name is string=. There are no string test functions that correspond to >, >=, or <=.

message
Print a message in the echo area. The first argument is a string that can contain `%s', `%d', or `%c' to print the value of arguments that follow the string. The argument used by `%s' must be a string or a symbol; the argument used by `%d' must be a number. The argument used by `%c' must be an ascii code number; it will be printed as the character with that ASCII code.

setq
set
The setq function sets the value of its first argument to the value of the second argument. The first argument is automatically quoted by setq. It does the same for succeeding pairs of arguments. Another function, set, takes only two arguments and evaluates both of them before setting the value returned by its first argument to the value returned by its second argument.

buffer-name
Without an argument, return the name of the buffer, as a string.

buffer-file-name
Without an argument, return the name of the file the buffer is visiting.

current-buffer
Return the buffer in which Emacs is active; it may not be the buffer that is visible on the screen.

other-buffer
Return the most recently selected buffer (other than the buffer passed to other-buffer as an argument and other than the current buffer).

switch-to-buffer
Select a buffer for Emacs to be active in and display it in the current window so users can look at it. Usually bound to C-x b.

set-buffer
Switch Emacs' attention to a buffer on which programs will run. Don't alter what the window is showing.

buffer-size
Return the number of characters in the current buffer.

point
Return the value of the current position of the cursor, as an integer counting the number of characters from the beginning of the buffer.

point-min
Return the minimum permissible value of point in the current buffer. This is 1, unless narrowing is in effect.

point-max
Return the value of the maximum permissible value of point in the current buffer. This is the end of the buffer, unless narrowing is in effect.


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

3.12 Exercises


[ << ] [ >> ]           [Top] [Contents] [Index] [ ? ]

This document was generated by Dohn Arms on March, 6 2005 using texi2html