Previous Table of Contents Next


2.10.4. A let Expression

Another way to specify a local variable is to use let. A let expression binds variables to values locally, for use within an expression, but then, on leaving the expression, the Lisp interpreter restores the values of the next higher level. (Usually, the next higher level is the level of the global variables, but a let expression may be embedded in a let expression, in which case the enclosing expression becomes the next higher level.)

Here is an example. First, the two symbols location and temperature are set to “Venus” and “hot” as global variables using the built-in function setq. Second, a let expression sets the variables locally to “Pluto” and “cold”. Finally, the two symbols are written alone, not within parentheses.

When you evaluate each list in sequence, first you see the value “Venus” for location and then “hot” for temperature. After evaluating the let expression, you see the value “On Pluto, it is cold.”. Finally, when you evaluate location and temperature, you see “Venus” and “hot”, their global values. (Here, as usual, → may be read as evaluates to; the glyph points to the value returned by evaluating the expression.)

   (setq location “Venus”)    → “Venus”
   (setq temperature “hot”)    → “hot”

   (let ((location “Pluto”)
       (temperature “cold”))
    (format “On %s, it is %s.” location temperature))
                   → “On Pluto, it is cold.”

   location                 → “Venus”
   temperature                 → “hot”

In this example, location and temperature are first set as global variables. Then the let expression binds location to “Pluto” and temperature to “cold” as local variables within it. When the format function creates a string, using location and temperature as arguments, the values they hold are “Pluto” and “cold”, which are the local values. Finally, when the Lisp interpreter evaluates location and temperature outside the let expression, it returns their values as global variables.

Technically speaking, 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, as in the example, 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, in this case a format expression. The body usually consists of one or more lists.

The symbols in the varlist are the variables that are given initial, local values by the let special form. Symbols by themselves are given the initial value 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.

A template for a let expression looks like this:

   (let varlist body ...)

In programming, you will use let expressions frequently.

2.10.5. Buffer-Local Variables

Buffer-local variables are frequently used to customize a mode, which sets up Emacs for work of a particular sort. For example, C mode makes it easier to write code in the C programming language. Ada mode makes it easier to write code in the Ada programming language. Calc mode provides a sophisticated calculator and mathematical tool. Calendar mode provides astronomical (Julian) day numbers and other conventional calendars. Mail mode is for mail. W3 mode is for Web browsing. Gnus mode is for reading net news and mail. Emacs has a rather large number of different modes.

Each buffer has one major mode at any time (but may have several minor modes). The simplest mode is Fundamental, which has no mode-specific redefinitions or variable settings. In Fundamental mode, each option is in its default state.

Consider Perl, which helps you write Perl scripts. You can change a buffer to Perl mode by typing M-x perl-mode or arrange to enter Perl mode automatically with certain files.9


9One way to enter Perl mode automatically is to add # -*-Perl-*- to the first line of your Perl script so it looks like this:
   #!/usr/bin/perl--# -*-Perl-*-

A second way is to arrange that Emacs recognize an appropriate filename suffix, such as .pl, as indicating a file to be visited in Perl mode. Similarly, .c indicates a file to be visited in C mode. The source file, perl-mode.el explains how to do this. (And because you have Emacs, which you need to run Emacs Lisp, you have access to this source file, an advantage of the form of distribution used by Emacs.) You can also consult the section “How Major Modes Are Chosen” in The GNU Emacs Lisp Reference Manual.

When you type M-x perl-mode, or otherwise start Perl mode, the first thing Emacs does is kill all existing local variables, which switches the buffer to Fundamental mode. Perl mode builds on top of this foundation.

Perl mode sets the mode-name buffer-local variable to the string “Perl” and the major-mode buffer local variable to the symbol perl-mode. It makes comment-start a buffer local variable with the expression

   (make-local-variable ‘comment-start)

and sets its value with the expression

   (setq comment-start “# “)

You will note that despite the name, make-local-variable makes a variable buffer local; it does not create what is called a local rather than a buffer-local variable. The word buffer was left out of make-local-variable in order to make the function name shorter.

Also, because comment-start is used in more than 20 different modes, it might have been better to have used the function make-variable-buffer-local just once when Emacs was first written; but Emacs grows incrementally, and each person who wrote a new mode decided to be careful and make comment-start a local variable.

In Perl mode, comment-start, comment-end, and others are all buffer-local variables. You can examine how buffer-local variables are created and used in more detail by looking at your copy of the perl-mode.el file or another mode-creating source file.


Previous Table of Contents Next