Lisp

Various forms of Lisp have been around since the 1950s. It is traditionally associated with artificial intelligence applications, for which Lisp is well-suited because it permits symbolic computation, can treat code as data, and simplifies building very complicated data structures. But Lisp is much more than just an AI language. It is applicable to a wide range of problems, a fact that is frequently overlooked by computer scientists but which is well known to Emacs users. Among the features that distinguish Lisp from other programming languages are:

Fully-parenthesized prefix notation

All expressions and function calls in Lisp are surrounded by parentheses,[1] and the function name always precedes the arguments to the function. So whereas in other languages you may be able to write:

x + y

to apply the + function to the arguments x and y, in Lisp you write

(+ x y)

"Prefix notation" means that the operator precedes the operands. When the operator is between the operands, it's called "infix notation."

Though unfamiliar, prefix notation has some benefits over infix notation. In infix languages, to write the sum of five variables you need four plus signs:

a + b + c + d + e

Lisp is more concise:

(+ a b c d e)

Also, questions of operator precedence do not arise. For example, is the value of

3 + 4 * 5

35 or 23? It depends on whether * has higher precedence than +. But in Lisp, the confusion vanishes:

(+ 3 (* 4 5))      ;result is 23
(* (+ 3 4) 5)      ;result is 35

(Comments in Lisp are introduced with a semicolon and continue to the end of the line.) Finally, while infix languages need commas to separate the arguments to a function:

foo(3 + 4, 5 + 6)

Lisp doesn't need that extra bit of syntax:

(foo (+ 3 4) (+ 5 6))
List data type

Lisp has a built-in data type called a list. A list is a Lisp object containing zero or more other Lisp objects, surrounded by parentheses. Here are some lists:

(hello there)      ;list containing two "symbols"
(1 2 "xyz")        ;two numbers and a string
(a (b c))          ;a symbol and a sublist (containing two symbols)
()                 ;the empty list

Lists can be assigned to variables, passed as arguments to functions and returned from them, constructed with such functions as cons and append, and taken apart with such functions as car and cdr. We'll be covering all that in plenty of detail later.

Garbage collection

Lisp is a garbage-collected language, which means that Lisp itself automatically reclaims the memory used by your program's data structures. By contrast, with languages such as C, one must explicitly allocate memory with malloc when it's needed, then explicitly release it with free. (The malloc/free approach and others like it in non-garbage-collecting languages are prone to abuse. Prematurely releasing allocated memory is one of the world's greatest sources of program errors, and forgetting to release allocated memory can cause programs to "bloat" until all available memory is used up.)

For all the convenience that garbage collection affords the programmer, it also has a drawback: periodically, Emacs stops everything it's doing and displays the message "Garbage collecting…" to the user. The user cannot use Emacs until garbage collection is finished.[2] This usually takes only a second or less, but it may happen very often. Later on we'll learn some programming practices that help to reduce the amount of garbage collection that takes place.

The word expression usually means any piece of Lisp code or any Lisp data structure. All Lisp expressions, whether code or data, can be evaluated by the Lisp interpreter built into Emacs to make them yield some computational result. The effect of evaluating a variable is to access the Lisp object previously stored in the variable. Evaluating a list is the way to invoke Lisp functions, as we'll see below.

Since the invention of Lisp, there have been many Lisp dialects, some of which barely resemble the others. MacLisp, Scheme, and Common Lisp are some of the better-known ones. Emacs Lisp is different from all of these. This book focuses only on Emacs Lisp.



[1] The proliferation of parentheses in Lisp is a feature that Lisp critics cheerfully decry as a sure sign of its inferiority. According to them, Lisp stands for "Lots of Infernal Stupid Parentheses." (In fact, Lisp stands for "List Processing.") In my view, the much simpler syntax renders Lisp code more readable, not less, than code in other languages, as I hope you will agree.

[2] Emacs uses a mark-and-sweep garbage collection scheme, which is one of the easiest ways to implement garbage collection. There are other approaches to implementing garbage collection that would not be so intrusive from the user's point of view; for instance, so-called "incremental" garbage collection can take place without bringing Emacs to a halt. Unfortunately, Emacs does not employ one of these more advanced approaches.

Get Writing GNU Emacs Extensions now with the O’Reilly learning platform.

O’Reilly members experience books, live events, courses curated by job role, and more from O’Reilly and nearly 200 top publishers.