Книга: Learning GNU Emacs, 3rd Edition
11.2.1 Statement Blocks
11.2.1 Statement Blocks
We have seen that a statement block can be defined using the let function. We also saw that while and save-excursion include statement blocks. Other important constructs also define statement blocks: progn and other forms of let.
progn, the most basic, has the form:
(progn
statement-block)
progn is a simple way of making a block of statements look like a single one, somewhat like the curly braces of Java or the begin
and end
of Pascal. The value returned by progn is the value returned by the last statement in the block. progn is especially useful with control structures like if (see the following discussion) that, unlike while, do not include statement blocks.
The let function has other forms as well. The simplest is:
(let (var1 var2...)
statement-block)
In this case, instead of a list of (var value)
pairs, there is simply a list of variable names. As with the other form of let, these become local variables accessible in the statement block. However, instead of initializing them to given values, they are all just initialized to nil
. You can actually mix both forms within the same let statement, for example:
(let (var1 (var2 value2) var3 ...)
statement-block)
In the form of let we saw first, the initial values for the local variables can be function calls (remember that all functions return values). All such functions are evaluated before any values are assigned to variables. However, there may be cases in which you want the values of some local variables to be available for computing the values of others. This is where let*, the final version of let, comes in. let* steps through its assignments in order, assigning each local variable a value before moving on to the next.
For example, let's say we want to write a function goto-percent that allows you to go to a place in the current buffer expressed as a percentage of the text in the buffer. Here is one way to write this function:
(defun goto-percent (pct)
(interactive "nGoto percent: ")
(let* ((size (point-max))
(charpos (/ (* size pct) 100)))
(goto-char charpos)))
As we saw earlier, the interactive function is used to prompt users for values of arguments. In this case, it prompts for the integer value of the argument pct. Then the let* function initializes size to the size of the buffer in characters, then uses that value to compute the character position charpos that is pct (percent) of the buffer's size. Finally, the call of goto-char causes point to be moved to that character position in the current window.
The important thing to notice is that if we had used let instead of let*, the value of size would not be available when computing the value of charpos. let* can also be used in the (var1 var2 ...)
format, just like let, but there wouldn't be any point in doing so.
We should also note that a more efficient way to write goto-percent is this:
(defun goto-percent (pct)
(interactive "nPercent: ")
(goto-char (/ (* pct (point-max)) 100)))
- Throwing Exceptions Using the throw Statement
- Conditional Statements
- The badblocks Command
- Special Statements: for, while, and Others
- The for Statement
- The while Statement
- The until Statement
- The shift Statement
- The if Statement
- The case Statement
- The break and exit Statements
- 3.1.3 Terminating Program Statements