All Things Variables
Time to get into Variables.
If you are used to most programming languages, setting and updating
variables is the way you operate. There are a few ways this happens in
Emacs Lisp, but the most fundamental way is via
The special form
setq is extremely simple. It sets the value of a
symbol, which can be referenced later:
ELISP> (setq x 10) 10 ELISP> (+ x x) 20
There is another, similar function:
The special form
defvar is similar in spirit to setq.
It allows you to define special variables, give them default values if
they do not already have values, and provide documentation for what
that variable "means". Some examples:
(defvar user-name "Joel" "The name of the person currently using Emacs.") (defvar pomodoro-done-hook nil "Hook that gets done whenever a pomodoro is finished.") (defvar my-favorite-numbers '(4 8 15 16 23 42))
defvar whenever you want to "declare" a variable to have some
special, global meaning.
Emacs Lisp is not the most opinionated of Lisps, so it lets you do all
the imperative programming that you want. However, a cleaner style of
handling variables is
ELISP> (let ((x 10)) (+ x x)) 20
Let takes a list of symbol and value bindings, and then evaluates
body, which represents the remaining arguments to
Another slightly more difficult example should help clarify the concept
ELISP> (let ((x 10)) (list (let ((x "hi")) x) x)) ("hi" 10)
This example illustrates how
let changes bindings. There are two
let calls in this fragment. The outer call sets the value of the
x to 10. After this happens, the body call occurs. Within the
list is a second
let form. This
let binds "hi" to the
x, which is then returned from the
let. This value ("hi")
then gets made into a list, along with the original value of x, which
was 10. Both of these then get returned, which gives us
The bindings list for
let can take multiple bindings, which will all
then be available when the body is executed:
ELISP> (let ((a "Heya") (b "worldz")) (concat a " " b)) "Heya worldz"
There is another form of
let*, which makes each
binding available to
the next binding when it is evaluated. This is actually extremely
useful, but when I first encountered this idea the usefulness was not
immediately apparent. So, lets have one final example, shall we?
Lets look at a quick regular expression example:
ELISP> (let* ((filename "2012-09-10-a-blog-post.markdown") (file-without-extension-rx "\\(.*\\).markdown") (regular-filename (progn (string-match file-without-extension-rx filename) (match-string 1 filename)))) (message "The filename sans extension was: %s" regular-filename)) "The filename sans extension was: 2012-09-10-a-blog-post"
Notice how the
regular-filename value comes from a compound
expression, and that the arguments two both function calls come from
the previous bindings. This is really, really useful in practice.
Well, that's about it for the basics of Emacs Lisp. With the Info documentation and the documentation for the various parts of Emacs, you should be equipped to hack the good hacks.
Of course, I'm not done helping you learn Emacs Lisp. There are many areas of the Emacs APIs that can use some simplification. And then, there is the reorganization thing that will happen when this series gets rolled into book form. So, stay tuned.