Previous | Table of Contents | Next |
The defmacro built-in function allows you define new features in Emacs Lisp.
A macro is defined somewhat like a function, except that instead of telling the Lisp interpreter how to compute a value, a macro definition tells the interpreter how to create a different Lisp expression from its arguments; that new expression computes the value. The new expression is the expansion of the macro.
A macro definition has up to four parts:
This sequence is like that of a function definition, except a macro has no interactive part.
For example, the following macro definition defines a construct to increment a variable, as in a counter. It adds one to the variable:
(defmacro inc (variable) (list setq variable (list + 1 variable)))
When evaluated, the macro definition returns inc, which you use as a function:
(setq foo 3) → 3
(inc foo) → 4
foo → 4
When a macro is defined, the Lisp interpreter does not return a function definition; instead, it returns an alternate expression, the expansion of the macro.
The macroexpand built-in function shows expansion:
(defmacro inc (variable) (list setq variable (list + 1 variable))) (macroexpand (inc foo)) -> (setq foo (+ 1 foo))
Put another way, the expression (inc foo) is a shorthand for the expression (setq foo (+ 1 foo)); it is the latter expression that the Lisp interpreter ends up evaluating, after first internally expanding the macro.
In any situation where you use a macro, you could have done without, except that a macro often simplifies writing what is otherwise a complex and repeated set of forms.
list, as you might suspect from its name, creates a list out of its arguments. It can take any number of arguments, each of which becomes an element of the list created; or it can take zero arguments.
The lists specified in the body of a macro definition are created using the built-in function list or else using the macro backquote (which is described in the next section).
(list) → nil (list foo bar) → (foo bar)
Note that list creates a list of its arguments, whereas cons prepends its first argument to an already existing list:
(list blue violet) → (blue violet) (cons green (blue violet)) → (green blue violet)
Macro definitions often consist of large list structures that are hard to write and hard to read once written. They would be too complex for use, except for a macro and a special marker that allow you to evaluate the elements of a list selectively.
The macro is called backquote and looks like ` rather than like a regular quote . The special marker looks like a comma ,.
Here is a quoted list; when evaluated, the list is returned as-is:
(red (+ 2 3) orange) → (red (+ 2 3) orange)
Here is a backquoted list, with one element marked with a comma ,; when evaluated, the unmarked parts of the list are returned as-is, but the marked element is evaluated:
`(red ,(+ 2 3) orange) → (red 5 orange)
This latter example works exactly as if you had used list and then quoted (not backquoted) the elements that were to stay the same:
(list red (+ 2 3) orange) → (red 5 orange)
In a sense, backquote ` and the special marker , are the photographic negative of list and quote.
Another special marker ,@ splices an evaluated value such that its elements enter the list at the same level as the other elements of the list, rather than as elements inside their own list.
For more information, see the section Macros in The GNU Emacs Lisp Reference Manual.
A property list, or plist for short, is a list of paired elements stored in the property list cell of a symbol. Each of the pairs associates a property name (usually a symbol) with a property or value.
Often, property lists are used to record information about a symbol, such as its documentation as a variable or the name of the file where it was defined.
For example, suppose we want to say that the characteristic of tigers is that they are fierce and the characteristic of dogs is that they bark. We can do that with property lists this way:
(put tiger characteristic fierce) (put dog characteristic barks)
Here is the template:
(put symbol property value)
put puts on the symbols property a value. The value can be a symbol, a string, or any other kind of Lisp object.
Then, to get the characteristic, evaluate expressions such as the following:
(get tiger characteristic) → fierce (get dog characteristic) → barks
Here is the template:
(get symbol property)
A more subtle use of property lists is illustrated by the Emacs Lisp code for converting a Texinfo file into Info. In the texnfmt.el file, you can see how the value of a property is extracted from a symbol and then executed as code. Although this may seem at first a rather roundabout way to evaluate a function, its advantage is that the method permits people to add new features to Texinfo easily and safely.
Previous | Table of Contents | Next |