Instant Access to An introduction to programming in emacs lisp 2nd Edition Robert J. Chassell ebook Full Chapters
Instant Access to An introduction to programming in emacs lisp 2nd Edition Robert J. Chassell ebook Full Chapters
https://ebookultra.com/download/an-introduction-to-programming-using-
alice-2-2-2nd-edition-charles-w-herbert/
https://ebookultra.com/download/an-introduction-to-stata-
programming-1st-edition-christopher-f-baum/
https://ebookultra.com/download/common-lisp-a-gentle-introduction-to-
symbolic-computation-david-s-touretzky/
https://ebookultra.com/download/introduction-to-computing-and-
programming-in-python-a-multimedia-approach-mark-j-guzdial/
Python Programming An Introduction to Computer Science
John M. Zelle
https://ebookultra.com/download/python-programming-an-introduction-to-
computer-science-john-m-zelle/
https://ebookultra.com/download/c-programming-an-introduction-rajiv-
chopra/
https://ebookultra.com/download/programming-concepts-in-c-2nd-edition-
robert-burns/
https://ebookultra.com/download/an-introduction-to-property-law-in-
australia-third-edition-edition-robert-chambers/
https://ebookultra.com/download/an-introduction-to-international-
criminal-law-and-procedure-robert-cryer/
An introduction to programming in emacs lisp 2nd
Edition Robert J. Chassell Digital Instant Download
Author(s): Robert J. Chassell
ISBN(s): 9781882114436, 1882114434
Edition: 2nd
File Details: PDF, 1.06 MB
Year: 2001
Language: english
An Introduction to
by Robert J. Chassell
Copyright c 1990, 1991, 1992, 1993, 1994, 1995, 1997, 2001, 2002 Free
Software Foundation, Inc.
Short Contents
Preface . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . xi
1 List Processing . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1
2 Practicing Evaluation . . . . . . . . . . . . . . . . . . . . . . . . . . . 23
3 How To Write Function Definitions . . . . . . . . . . . . . . . . . . 29
4 A Few Buffer–Related Functions . . . . . . . . . . . . . . . . . . . . 51
5 A Few More Complex Functions . . . . . . . . . . . . . . . . . . . . 63
6 Narrowing and Widening . . . . . . . . . . . . . . . . . . . . . . . . . 77
7 car, cdr, cons: Fundamental Functions . . . . . . . . . . . . . 81
8 Cutting and Storing Text . . . . . . . . . . . . . . . . . . . . . . . . . 89
9 How Lists are Implemented . . . . . . . . . . . . . . . . . . . . . . . 113
10 Yanking Text Back . . . . . . . . . . . . . . . . . . . . . . . . . . . . 117
11 Loops and Recursion . . . . . . . . . . . . . . . . . . . . . . . . . . . 121
12 Regular Expression Searches . . . . . . . . . . . . . . . . . . . . . . 149
13 Counting: Repetition and Regexps . . . . . . . . . . . . . . . . . . 167
14 Counting Words in a defun . . . . . . . . . . . . . . . . . . . . . . 181
15 Readying a Graph . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 203
16 Your ‘.emacs’ File . . . . . . . . . . . . . . . . . . . . . . . . . . . . 213
17 Debugging . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 231
18 Conclusion . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 239
Appendix A The the-the Function . . . . . . . . . . . . . . . . . . 241
Appendix B Handling the Kill Ring . . . . . . . . . . . . . . . . . . . 243
Appendix C A Graph with Labelled Axes . . . . . . . . . . . . . . . 255
Appendix D GNU Free Documentation License . . . . . . . . . . . 279
Index . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 287
ii
iii
Table of Contents
Preface . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . xi
On Reading this Text . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . xi
For Whom This is Written. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . xii
Lisp History . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . xiii
A Note for Novices . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . xiii
Thank You . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . xiv
1 List Processing . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1
1.1 Lisp Lists . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1
1.1.1 Lisp Atoms . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1
1.1.2 Whitespace in Lists . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3
1.1.3 GNU Emacs Helps You Type Lists . . . . . . . . . . . . . . . 3
1.2 Run a Program . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4
1.3 Generate an Error Message . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4
1.4 Symbol Names and Function Definitions . . . . . . . . . . . . . . . . . . 6
1.5 The Lisp Interpreter . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7
1.5.1 Byte Compiling. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8
1.6 Evaluation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8
1.6.1 Evaluating Inner Lists . . . . . . . . . . . . . . . . . . . . . . . . . . 9
1.7 Variables . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10
1.7.1 Error Message for a Symbol Without a Function . . 11
1.7.2 Error Message for a Symbol Without a Value . . . . 11
1.8 Arguments. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12
1.8.1 Arguments’ Data Types . . . . . . . . . . . . . . . . . . . . . . . . 13
1.8.2 An Argument as the Value of a Variable or List . . 13
1.8.3 Variable Number of Arguments . . . . . . . . . . . . . . . . . 14
1.8.4 Using the Wrong Type Object as an Argument . . 14
1.8.5 The message Function . . . . . . . . . . . . . . . . . . . . . . . . . 16
1.9 Setting the Value of a Variable . . . . . . . . . . . . . . . . . . . . . . . . . . 17
1.9.1 Using set . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 17
1.9.2 Using setq . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 18
1.9.3 Counting. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19
1.10 Summary . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 20
1.11 Exercises . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 20
2 Practicing Evaluation . . . . . . . . . . . . . . . . . . . . . 23
2.1 Buffer Names . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 23
2.2 Getting Buffers . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 25
2.3 Switching Buffers . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 26
2.4 Buffer Size and the Location of Point . . . . . . . . . . . . . . . . . . . . 27
2.5 Exercise . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 28
iv
17 Debugging . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 231
17.1 debug . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 231
17.2 debug-on-entry . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 232
17.3 debug-on-quit and (debug). . . . . . . . . . . . . . . . . . . . . . . . . . 234
17.4 The edebug Source Level Debugger . . . . . . . . . . . . . . . . . . . . 235
17.5 Debugging Exercises. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 237
ix
18 Conclusion . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 239
Index . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 287
x
On Reading this Text xi
Preface
Most of the GNU Emacs integrated environment is written in the pro-
gramming language called Emacs Lisp. The code written in this program-
ming language is the software—the sets of instructions—that tell the com-
puter what to do when you give it commands. Emacs is designed so that
you can write new code in Emacs Lisp and easily install it as an extension
to the editor.
(GNU Emacs is sometimes called an “extensible editor”, but it does much
more than provide editing capabilities. It is better to refer to Emacs as
an “extensible computing environment”. However, that phrase is quite a
mouthful. It is easier to refer to Emacs simply as an editor. Moreover,
everything you do in Emacs—find the Mayan date and phases of the moon,
simplify polynomials, debug code, manage files, read letters, write books—all
these activities are kinds of editing in the most general sense of the word.)
Although Emacs Lisp is usually thought of in association only with
Emacs, it is a full computer programming language. You can use Emacs
Lisp as you would any other programming language.
Perhaps you want to understand programming; perhaps you want to ex-
tend Emacs; or perhaps you want to become a programmer. This introduc-
tion to Emacs Lisp is designed to get you started: to guide you in learning
the fundamentals of programming, and more importantly, to show you how
you can teach yourself to go further.
Lisp History
Lisp was first developed in the late 1950s at the Massachusetts Institute
of Technology for research in artificial intelligence. The great power of the
Lisp language makes it superior for other purposes as well, such as writing
editor commands and integrated environments.
GNU Emacs Lisp is largely inspired by Maclisp, which was written at
MIT in the 1960s. It is somewhat inspired by Common Lisp, which became
a standard in the 1980s. However, Emacs Lisp is much simpler than Common
Lisp. (The standard Emacs distribution contains an optional extensions file,
‘cl.el’, that adds many Common Lisp features to Emacs Lisp.)
In addition to typing a lone keychord, you can prefix what you type with
C-u, which is called the ‘universal argument’. The C-u keychord passes an
argument to the subsequent command. Thus, to indent a region of plain
text by 6 spaces, mark the region, and then type C-u 6 M-C-\. (If you do
not specify a number, Emacs either passes the number 4 to the command
or otherwise runs the command differently than it would otherwise.) See
section “Numeric Arguments” in The GNU Emacs Manual.
If you are reading this in Info using GNU Emacs, you can read through
this whole document just by pressing the space bar, hSPCi. (To learn about
Info, type C-h i and then select Info.)
A note on terminology: when I use the word Lisp alone, I often am
referring to the various dialects of Lisp in general, but when I speak of
Emacs Lisp, I am referring to GNU Emacs Lisp in particular.
Thank You
My thanks to all who helped me with this book. My especial thanks to
Jim Blandy, Noah Friedman, Jim Kingdon, Roland McGrath, Frank Ritter,
Randy Smith, Richard M. Stallman, and Melissa Weisshaus. My thanks
also go to both Philip Johnson and David Stampe for their patient encour-
agement. My mistakes are my own.
Robert J. Chassell
Lisp Atoms 1
1 List Processing
To the untutored eye, Lisp is a strange programming language. In Lisp
code there are parentheses everywhere. Some people even claim that the
name stands for ‘Lots of Isolated Silly Parentheses’. But the claim is un-
warranted. Lisp stands for LISt Processing, and the programming language
handles lists (and lists of lists) by putting them between parentheses. The
parentheses mark the boundaries of the list. Sometimes a list is preceded by
a single apostrophe or quotation mark, ‘’’. Lists are the basis of Lisp.
‘+’. On the other hand, unlike an atom, a list can be split into parts. (See
Chapter 7, “car cdr & cons Fundamental Functions”, page 81.)
In a list, atoms are separated from each other by whitespace. They can
be right next to a parenthesis.
The printed representation of both atoms and lists are called symbolic
expressions or, more concisely, s-expressions. The word expression by itself
can refer to either the printed representation, or to the atom or list as it
is held internally in the computer. Often, people use the term expression
indiscriminately. (Also, in many texts, the word form is used as a synonym
for expression.)
Incidentally, the atoms that make up our universe were named such when
they were thought to be indivisible; but it has been found that physical atoms
are not indivisible. Parts can split off an atom or it can fission into two parts
of roughly equal size. Physical atoms were named prematurely, before their
truer nature was found. In Lisp, certain kinds of atom, such as an array, can
be separated into parts; but the mechanism for doing this is different from
the mechanism for splitting a list. As far as list operations are concerned,
the atoms of a list are unsplittable.
There are many kinds of atom in nature but only a few in Lisp: for
example, numbers, such as 37, 511, or 1729, and symbols, such as ‘+’, ‘foo’,
or ‘forward-line’. The words we have listed in the examples above are
all symbols. In everyday Lisp conversation, the word “atom” is not often
used, because programmers usually try to be more specific about what kind
of atom they are dealing with. Lisp programming is mostly about symbols
(and sometimes numbers) within lists. (Incidentally, the preceding three
word parenthetical remark is a proper list in Lisp, since it consists of atoms,
which in this case are symbols, separated by whitespace and enclosed by
parentheses, without any non-Lisp punctuation.)
GNU Emacs Helps You Type Lists 3
its closing parenthesis match its opening parenthesis. (See section “Major
Modes” in The GNU Emacs Manual, for more information about Emacs’
modes.)
harmless activity; and indeed, we will often try to generate error messages
intentionally. Once you understand the jargon, error messages can be in-
formative. Instead of being called “error” messages, they should be called
“help” messages. They are like signposts to a traveller in a strange country;
deciphering them can be hard, but once understood, they can point the way.
The error message is generated by a built-in GNU Emacs debugger. We
will ‘enter the debugger’. You get out of the debugger by typing q.
What we will do is evaluate a list that is not quoted and does not have
a meaningful command as its first element. Here is a list almost exactly the
same as the one we just used, but without the single-quote in front of it.
Position the cursor right after it and type C-x C-e:
(this is an unquoted list)
What you see depends on which version of Emacs you are running. GNU
Emacs version 21 provides more information than version 20 and before.
First, the more recent result of generating an error; then the earlier, version
20 result.
In GNU Emacs version 21, a ‘*Backtrace*’ window will open up and you
will see the following in it:
---------- Buffer: *Backtrace* ----------
Debugger entered--Lisp error: (void-function this)
(this is an unquoted list)
eval((this is an unquoted list))
eval-last-sexp-1(nil)
eval-last-sexp(nil)
call-interactively(eval-last-sexp)
---------- Buffer: *Backtrace* ----------
Your cursor will be in this window (you may have to wait a few seconds
before it becomes visible). To quit the debugger and make the debugger
window go away, type:
q
Please type q right now, so you become confident that you can get out of
the debugger. Then, type C-x C-e again to re-enter it.
Based on what we already know, we can almost read this error message.
You read the ‘*Backtrace*’ buffer from the bottom up; it tells you what
Emacs did. When you typed C-x C-e, you made an interactive call to the
command eval-last-sexp. eval is an abbreviation for ‘evaluate’ and sexp
is an abbreviation for ‘symbolic expression’. The command means ‘evaluate
last symbolic expression’, which is the expression just before your cursor.
Each line above tells you what the Lisp interpreter evaluated next. The
most recent action is at the top. The buffer is called the ‘*Backtrace*’
buffer because it enables you to track Emacs backwards.
6 Chapter 1: List Processing
‘Bob’; however, I am not the letters ‘B’, ‘o’, ‘b’ but am the consciousness
consistently associated with a particular life-form. The name is not me, but
it can be used to refer to me.
In Lisp, one set of instructions can be attached to several names. For
example, the computer instructions for adding numbers can be linked to the
symbol plus as well as to the symbol + (and are in some dialects of Lisp).
Among humans, I can be referred to as ‘Robert’ as well as ‘Bob’ and by
other words as well.
On the other hand, a symbol can have only one function definition at-
tached to it at a time. Otherwise, the computer would be confused as to
which definition to use. If this were the case among people, only one person
in the world could be named ‘Bob’. However, the function definition to which
the name refers can be changed readily. (See Section 3.2, “Install a Function
Definition”, page 31.)
Since Emacs Lisp is large, it is customary to name symbols in a way that
identifies the part of Emacs to which the function belongs. Thus, all the
names for functions that deal with Texinfo start with ‘texinfo-’ and those
for functions that deal with reading mail start with ‘rmail-’.
The third and final complication is this: if the function that the Lisp
interpreter is looking at is not a special form, and if it is part of a list, the
Lisp interpreter looks to see whether the list has a list inside of it. If there
is an inner list, the Lisp interpreter first figures out what it should do with
the inside list, and then it works on the outside list. If there is yet another
list embedded inside the inner list, it works on that one first, and so on.
It always works on the innermost list first. The interpreter works on the
innermost list first, to evaluate the result of that list. The result may be
used by the enclosing expression.
Otherwise, the interpreter works left to right, from one expression to the
next.
1.6 Evaluation
When the Lisp interpreter works on an expression, the term for the ac-
tivity is called evaluation. We say that the interpreter ‘evaluates the expres-
sion’. I’ve used this term several times before. The word comes from its
use in everyday language, ‘to ascertain the value or amount of; to appraise’,
according to Webster’s New Collegiate Dictionary.
After evaluating an expression, the Lisp interpreter will most likely return
the value that the computer produces by carrying out the instructions it
found in the function definition, or perhaps it will give up on that function
and produce an error message. (The interpreter may also find itself tossed,
so to speak, to a different function or it may attempt to repeat continually
what it is doing for ever and ever in what is called an ‘infinite loop’. These
actions are less common; and we can ignore them.) Most frequently, the
interpreter returns a value.
Evaluating Inner Lists 9
result of the computer carrying out the instructions in the function definition
attached to that name. If a symbol by itself is evaluated, something different
happens, as we will see in the next section.
1.7 Variables
In Emacs Lisp, a symbol can have a value attached to it just as it can
have a function definition attached to it. The two are different. The function
definition is a set of instructions that a computer will obey. A value, on the
other hand, is something, such as number or a name, that can vary (which
is why such a symbol is called a variable). The value of a symbol can be any
expression in Lisp, such as a symbol, number, list, or string. A symbol that
has a value is often called a variable.
A symbol can have both a function definition and a value attached to it
at the same time. Or it can have just one or the other. The two are separate.
This is somewhat similar to the way the name Cambridge can refer to the
city in Massachusetts and have some information attached to the name as
well, such as “great programming center”.
Another way to think about this is to imagine a symbol as being a chest of
drawers. The function definition is put in one drawer, the value in another,
and so on. What is put in the drawer holding the value can be changed
without affecting the contents of the drawer holding the function definition,
and vice-versa.
The variable fill-column illustrates a symbol with a value attached to
it: in every GNU Emacs buffer, this symbol is set to some value, usually 72
or 70, but sometimes to some other value. To find the value of this symbol,
evaluate it by itself. If you are reading this in Info inside of GNU Emacs,
you can do this by putting the cursor after the symbol and typing C-x C-e:
fill-column
After I typed C-x C-e, Emacs printed the number 72 in my echo area. This
is the value for which fill-column is set for me as I write this. It may
be different for you in your Info buffer. Notice that the value returned as
a variable is printed in exactly the same way as the value returned by a
function carrying out its instructions. From the point of view of the Lisp
interpreter, a value returned is a value returned. What kind of expression it
came from ceases to matter once the value is known.
A symbol can have any value attached to it or, to use the jargon, we can
bind the variable to a value: to a number, such as 72; to a string, "such as
this"; to a list, such as (spruce pine oak); we can even bind a variable to
a function definition.
A symbol can be bound to a value in several ways. See Section 1.9,
“Setting the Value of a Variable”, page 17, for information about one way
to do this.
Error Message for a Symbol Without a Value 11
This backtrace is different from the very first error message we saw,
which said, ‘Debugger entered--Lisp error: (void-function this)’. In
this case, the function does not have a value as a variable; while in the other
error message, the function (the word ‘this’) did not have a definition.
In this experiment with the +, what we did was cause the Lisp interpreter
to evaluate the + and look for the value of the variable instead of the function
definition. We did this by placing the cursor right after the symbol rather
than after the parenthesis of the enclosing list as we did before. As a conse-
quence, the Lisp interpreter evaluated the preceding s-expression, which in
this case was the + by itself.
Since + does not have a value bound to it, just the function definition,
the error message reported that the symbol’s value as a variable was void.
In GNU Emacs version 20 and before, your error message will say:
Symbol’s value as variable is void: +
The meaning is the same as in GNU Emacs 21.
1.8 Arguments
To see how information is passed to functions, let’s look again at our old
standby, the addition of two plus two. In Lisp, this is written as follows:
(+ 2 2)
If you evaluate this expression, the number 4 will appear in your echo
area. What the Lisp interpreter does is add the numbers that follow the +.
The numbers added by + are called the arguments of the function +.
These numbers are the information that is given to or passed to the function.
The word ‘argument’ comes from the way it is used in mathematics and
does not refer to a disputation between two people; instead it refers to the
information presented to the function, in this case, to the +. In Lisp, the
arguments to a function are the atoms or lists that follow the function. The
values returned by the evaluation of these atoms or lists are passed to the
function. Different functions require different numbers of arguments; some
functions require none at all.1
1
It is curious to track the path by which the word ‘argument’ came to have two differ-
ent meanings, one in mathematics and the other in everyday English. According to
the Oxford English Dictionary, the word derives from the Latin for ‘to make clear,
prove’; thus it came to mean, by one thread of derivation, ‘the evidence offered as
proof’, which is to say, ‘the information offered’, which led to its meaning in Lisp.
But in the other thread of derivation, it came to mean ‘to assert in a manner against
which others may make counter assertions’, which led to the meaning of the word as a
disputation. (Note here that the English word has two different definitions attached to
it at the same time. By contrast, in Emacs Lisp, a symbol cannot have two different
function definitions at the same time.)
An Argument as the Value of a Variable or List 13
to the function concat are the strings "The " and " red foxes." and the
list (number-to-string (+ 2 fill-column)).
(concat "The " (number-to-string (+ 2 fill-column)) " red foxes.")
If you evaluate this expression—and if, as with my Emacs, fill-column
evaluates to 72—"The 74 red foxes." will appear in the echo area. (Note
that you must put spaces after the word ‘The’ and before the word ‘red’
so they will appear in the final string. The function number-to-string
converts the integer that the addition function returns to a string. number-
to-string is also known as int-to-string.)
(*) ⇒ 1
In this set, the functions have one argument each:
(+ 3) ⇒ 3
(* 3) ⇒ 3
In this set, the functions have three arguments each:
(+ 3 4 5) ⇒ 12
(* 3 4 5) ⇒ 60
In GNU Emacs version 21, you will create and enter a ‘*Backtrace*’
buffer that says:
---------- Buffer: *Backtrace* ----------
Debugger entered--Lisp error:
(wrong-type-argument number-or-marker-p hello)
+(2 hello)
eval((+ 2 (quote hello)))
eval-last-sexp-1(nil)
eval-last-sexp(nil)
call-interactively(eval-last-sexp)
---------- Buffer: *Backtrace* ----------
As usual, the error message tries to be helpful and makes sense after you
learn how to read it.
The first part of the error message is straightforward; it says ‘wrong type
argument’. Next comes the mysterious jargon word ‘number-or-marker-p’.
This word is trying to tell you what kind of argument the + expected.
The symbol number-or-marker-p says that the Lisp interpreter is try-
ing to determine whether the information presented it (the value of the
argument) is a number or a marker (a special object representing a buffer
position). What it does is test to see whether the + is being given numbers to
add. It also tests to see whether the argument is something called a marker,
which is a specific feature of Emacs Lisp. (In Emacs, locations in a buffer
are recorded as markers. When the mark is set with the C-@ or C- hSPCi
command, its position is kept as a marker. The mark can be considered a
number—the number of characters the location is from the beginning of the
buffer.) In Emacs Lisp, + can be used to add the numeric value of marker
positions as numbers.
The ‘p’ of number-or-marker-p is the embodiment of a practice started
in the early days of Lisp programming. The ‘p’ stands for ‘predicate’. In the
jargon used by the early Lisp researchers, a predicate refers to a function
to determine whether some property is true or false. So the ‘p’ tells us that
number-or-marker-p is the name of a function that determines whether it
is true or false that the argument supplied is a number or a marker. Other
Lisp symbols that end in ‘p’ include zerop, a function that tests whether its
argument has the value of zero, and listp, a function that tests whether its
argument is a list.
Finally, the last part of the error message is the symbol hello. This is the
value of the argument that was passed to +. If the addition had been passed
the correct type of object, the value passed would have been a number, such
as 37, rather than a symbol like hello. But then you would not have got
the error message.
16 Chapter 1: List Processing
In GNU Emacs version 20 and before, the echo area displays an error
message that says:
Wrong type argument: number-or-marker-p, hello
This says, in different words, the same as the top line of the ‘*Backtrace*’
buffer.
The list (rose violet daisy buttercup) will appear in the echo area. This
is what is returned by the set function. As a side effect, the symbol flowers
is bound to the list ; that is, the symbol flowers, which can be viewed as a
variable, is given the list as its value. (This process, by the way, illustrates
how a side effect to the Lisp interpreter, setting the value, can be the primary
effect that we humans are interested in. This is because every Lisp function
must return a value if it does not get an error, but it will only have a side
effect if it is designed to have one.)
After evaluating the set expression, you can evaluate the symbol flowers
and it will return the value you just set. Here is the symbol. Place your
cursor after it and type C-x C-e.
flowers
When you evaluate flowers, the list (rose violet daisy buttercup) ap-
pears in the echo area.
Incidentally, if you evaluate ’flowers, the variable with a quote in front
of it, what you will see in the echo area is the symbol itself, flowers. Here
is the quoted symbol, so you can try this:
’flowers
Note also, that when you use set, you need to quote both arguments to
set, unless you want them evaluated. Since we do not want either argument
evaluated, neither the variable flowers nor the list (rose violet daisy
buttercup), both are quoted. (When you use set without quoting its first
argument, the first argument is evaluated before anything else is done. If
you did this and flowers did not have a value already, you would get an
error message that the ‘Symbol’s value as variable is void’; on the other
hand, if flowers did return a value after it was evaluated, the set would
attempt to set the value that was returned. There are situations where this
is the right thing for the function to do; but such situations are rare.)
1.9.3 Counting
Here is an example that shows how to use setq in a counter. You might
use this to count how many times a part of your program repeats itself. First
set a variable to zero; then add one to the number each time the program
repeats itself. To do this, you need a variable that serves as a counter, and
two expressions: an initial setq expression that sets the counter variable to
zero; and a second setq expression that increments the counter each time it
is evaluated.
(setq counter 0) ; Let’s call this the initializer.
order to evaluate this list, it must evaluate the variable counter and the
number 1. When it evaluates the variable counter, it receives its current
value. It passes this value and the number 1 to the + which adds them
together. The sum is then returned as the value of the inner list and passed
to the setq which sets the variable counter to this new value. Thus, the
value of the variable, counter, is changed.
1.10 Summary
Learning Lisp is like climbing a hill in which the first part is the steepest.
You have now climbed the most difficult part; what remains becomes easier
as you progress onwards.
In summary,
• Lisp programs are made up of expressions, which are lists or single
atoms.
• Lists are made up of zero or more atoms or inner lists, separated by
whitespace and surrounded by parentheses. A list can be empty.
• Atoms are multi-character symbols, like forward-paragraph, single
character symbols like +, strings of characters between double quota-
tion marks, or numbers.
• A number evaluates to itself.
• A string between double quotes also evaluates to itself.
• When you evaluate a symbol by itself, its value is returned.
• When you evaluate a list, the Lisp interpreter looks at the first symbol
in the list and then at the function definition bound to that symbol.
Then the instructions in the function definition are carried out.
• A single-quote, ’, tells the Lisp interpreter that it should return the
following expression as written, and not evaluate it as it would if the
quote were not there.
• Arguments are the information passed to a function. The arguments to
a function are computed by evaluating the rest of the elements of the
list of which the function is the first element.
• A function always returns a value when it is evaluated (unless it gets
an error); in addition, it may also carry out some action called a “side
effect”. In many cases, a function’s primary purpose is to create a side
effect.
1.11 Exercises
A few simple exercises:
• Generate an error message by evaluating an appropriate symbol that is
not within parentheses.
Exercises 21
2 Practicing Evaluation
Before learning how to write a function definition in Emacs Lisp, it is
useful to spend a little time evaluating various expressions that have already
been written. These expressions will be lists with the functions as their first
(and often only) element. Since some of the functions associated with buffers
are both simple and interesting, we will start with those. In this section, we
will evaluate a few of these. In another section, we will study the code of
several other buffer-related functions, to see how they were written.
Whenever you give an editing command to Emacs Lisp, such as the com-
mand to move the cursor or to scroll the screen, you are evaluating an ex-
pression, the first element of which is a function. This is how Emacs works.
When you type keys, you cause the Lisp interpreter to evaluate an expres-
sion and that is how you get your results. Even typing plain text involves
evaluating an Emacs Lisp function, in this case, one that uses self-insert-
command, which simply inserts the character you typed. The functions you
evaluate by typing keystrokes are called interactive functions, or commands;
how you make a function interactive will be illustrated in the chapter on
how to write function definitions. See Section 3.3, “Making a Function In-
teractive”, page 33.
In addition to typing keyboard commands, we have seen a second way
to evaluate an expression: by positioning the cursor after a list and typing
C-x C-e. This is what we will do in the rest of this section. There are other
ways to evaluate an expression as well; these will be described as we come
to them.
Besides being used for practicing evaluation, the functions shown in the
next few sections are important in their own right. A study of these functions
makes clear the distinction between buffers and files, how to switch to a
buffer, and how to determine a location within it.
the file, until you save the buffer. When you save the buffer, the buffer is
copied to the file and is thus saved permanently.
If you are reading this in Info inside of GNU Emacs, you can evaluate
each of the following expressions by positioning the cursor after it and typing
C-x C-e.
(buffer-name)
(buffer-file-name)
When I do this, ‘"introduction.texinfo"’ is the value returned by eval-
uating (buffer-name), and ‘"/gnu/work/intro/introduction.texinfo"’
is the value returned by evaluating (buffer-file-name). The former is the
name of the buffer and the latter is the name of the file. (In the expres-
sions, the parentheses tell the Lisp interpreter to treat buffer-name and
buffer-file-name as functions; without the parentheses, the interpreter
would attempt to evaluate the symbols as variables. See Section 1.7, “Vari-
ables”, page 10.)
In spite of the distinction between files and buffers, you will often find
that people refer to a file when they mean a buffer and vice-versa. Indeed,
most people say, “I am editing a file,” rather than saying, “I am editing a
buffer which I will soon save to a file.” It is almost always clear from context
what people mean. When dealing with computer programs, however, it is
important to keep the distinction in mind, since the computer is not as smart
as a person.
The word ‘buffer’, by the way, comes from the meaning of the word as
a cushion that deadens the force of a collision. In early computers, a buffer
cushioned the interaction between files and the computer’s central processing
unit. The drums or tapes that held a file and the central processing unit
were pieces of equipment that were very different from each other, working
at their own speeds, in spurts. The buffer made it possible for them to work
together effectively. Eventually, the buffer grew from being an intermediary,
a temporary holding place, to being the place where work is done. This
transformation is rather like that of a small seaport that grew into a great
city: once it was merely the place where cargo was warehoused temporarily
before being loaded onto ships; then it became a business and cultural center
in its own right.
Not all buffers are associated with files. For example, when you start
an Emacs session by typing the command emacs alone, without naming any
files, Emacs will start with the ‘*scratch*’ buffer on the screen. This buffer
is not visiting any file. Similarly, a ‘*Help*’ buffer is not associated with
any file.
If you switch to the ‘*scratch*’ buffer, type (buffer-name), position
the cursor after it, and type C-x C-e to evaluate the expression, the name
"*scratch*" is returned and will appear in the echo area. "*scratch*"
is the name of the buffer. However, if you type (buffer-file-name) in
Getting Buffers 25
the ‘*scratch*’ buffer and evaluate that, nil will appear in the echo area.
nil is from the Latin word for ‘nothing’; in this case, it means that the
‘*scratch*’ buffer is not associated with any file. (In Lisp, nil is also used
to mean ‘false’ and is a synonym for the empty list, ().)
Incidentally, if you are in the ‘*scratch*’ buffer and want the value
returned by an expression to appear in the ‘*scratch*’ buffer itself rather
than in the echo area, type C-u C-x C-e instead of C-x C-e. This causes the
value returned to appear after the expression. The buffer will look like this:
(buffer-name)"*scratch*"
You cannot do this in Info since Info is read-only and it will not allow you
to change the contents of the buffer. But you can do this in any buffer you
can edit; and when you write code or documentation (such as this book),
this feature is very useful.
switched back and forth from the ‘*scratch*’ buffer, other-buffer will
return that buffer.
You can see this by evaluating the expression:
(other-buffer)
You should see ‘#<buffer *scratch*>’ appear in the echo area, or the name
of whatever other buffer you switched back from most recently 1 .
In this case, the first argument to other-buffer tells it which buffer to skip—the
current one—and the second argument tells other-buffer it is OK to switch to a
visible buffer. In regular use, switch-to-buffer takes you to an invisible window
since you would most likely use C-x o (other-window) to go to another visible buffer.
Another Random Scribd Document
with Unrelated Content
should never forget him nor what he had now related to me, but
that I would try to forget what he had related in the beginning. The
Indians who were with me, following the thread of the conversation,
continued to entertain us with rational stories, and the evening was
spent very agreeably. In the morning, when we parted, the strange
Indian whom I had thus rebuked, shook me cordially by the hand,
saying: “Friend! you shall never be forgotten by me. Indeed I call
you my friend.”
1. What is the name of your tribe? Is it its original name; if not, how
was it formerly called?
5. Which among the tribes connected with you is that which you call
grandfather?
Indian nations or tribes connected with each other are not always
connected by blood or descended from the same original stock.
Some are admitted into the connexion by adoption. Such are the
Tuscaroras among the Six Nations; such the Cherokees among the
Lenni Lenape. Thus, in the year 1779, a deputation of fourteen men
came from the Cherokee nation to the council fire of the Delawares,
to condole with their grandfather on the loss of their head chief.247
There are tribes, on the other hand, who have wandered far from
the habitations of those connected with them by blood or
relationship. It is certain that they can no longer be benefited by the
general council fire. They, therefore, become a people by
themselves, and pass with us for a separate nation, if they only have
a name; nevertheless, (if I am rightly informed) they well know to
what stock or nation they originally belonged, and if questioned on
that subject, will give correct answers. It is therefore very important
to make these enquiries of any tribe or nation that a traveller may
find himself among. The analogy of languages is the best and most
unequivocal sign of connexion between Indian tribes; yet the
absence of that indication should not always be relied upon.
It may not be improper also to mention in this place that the purity
or correctness with which a language is spoken, will greatly help to
discover who is the head of the national family. For no where is the
language so much cultivated as in the vicinity of the great national
council fire, where the orators have the best opportunity of
displaying their talents. Thus the purest and most elegant dialect of
the Lenape language, is that of the Unami or Turtle tribe.
CHAPTER XLIV.
THE INDIANS AND THE WHITES COMPARED.
Those who have never taken the pains to enquire into the real
character and disposition of the American Indians, naturally
suppose, that a people who have no code of laws for their
government, but where every man is at liberty to do what he
pleases, where men never forget or forgive injuries, and take
revenge in their own way, often in the most cruel manner, and are
never satisfied until they have been revenged, must of course be
barbarians and savages; by which undefined words is understood
whatever is bad, wicked, and disgraceful to human nature.
Imagination is immediately at work to paint them as a species of
monsters, to whom cruelty is an appetite; a sort of human-shaped
tigers and panthers, strangers to the finer feelings, and who commit
acts of barbarity without any excitement but that of their depraved
inclination, and without even suspecting that there are such things in
nature as virtue on the one hand and crime on the other.
But nothing is so false as this picture of the Indians. The worst that
can be said of them is, that the passion of revenge is so strong in
their minds, that it carries them beyond all bounds. But set this
aside, and their character is noble and great. They have no written
laws, but they have usages founded on the most strict principles of
equity and justice. Murder with them is punished with death. It is
true, that as was the case not many centuries ago among the most
civilised nations of Europe, the death of a man may be compounded
for with his surviving relations; if, however, they do not choose to
accept of the terms offered, any one of them may become the
executioner of the murderer.
Every person who is well acquainted with the true character of the
Indians will admit that they are peaceable, sociable, obliging,
charitable, and hospitable among themselves, and that those virtues
are, as it were, a part of their nature. In their ordinary intercourse,
they are studious to oblige each other. They neither wrangle nor
fight; they live, I believe, as peaceably together as any people on
earth, and treat one another with the greatest respect. That they are
not devoid of tender feelings has been sufficiently shewn in the
course of this work. I do not mean to speak of those whose manners
have been corrupted by a long intercourse with the worst class of
white men; they are a degenerate race, very different from the true
genuine Indians whom I have attempted to describe.
“No faith can be placed in what the Indians promise at treaties; for
scarcely is a treaty concluded than they are again murdering us.”
Such is our complaint against these unfortunate people; but they will
tell you that it is the white men in whom no faith is to placed. They
will tell you, that there is not a single instance in which the whites
have not violated the engagements that they had made at treaties.
They say that when they had ceded lands to the white people, and
boundary lines had been established—“firmly established!” beyond
which no whites were to settle; scarcely was the treaty signed, when
white intruders again were settling and hunting on their lands! It is
true that when they preferred their complaints to the government,
the government gave them many fair promises, and assured them
that men would be sent to remove the intruders by force from the
usurped lands. The men, indeed, came, but with chain and compass
in their hands, taking surveys of the tracts of good land, which the
intruders, from their knowledge of the country, had pointed out to
them!
What was then to be done, when those intruders would not go off
from the land, but, on the contrary, increased in numbers? “Oh!”
said those people, (and I have myself frequently heard this language
in the Western country,) “a new treaty will soon give us all this land;
nothing is now wanting but a pretence to pick a quarrel with them!”
Well, but in what manner is this quarrel to be brought about? A
David Owen, a Walker, and many others might, if they were alive,
easily answer this question. A precedent, however, may be found, on
perusing Mr. Jefferson’s Appendix to his Notes on Virginia. On all
occasions, when the object is to murder Indians, strong liquor is the
main article required; for when you have them dead drunk, you may
do to them as you please, without running the risk of losing your
life. And should you find that the laws of your country may reach
you where you are, you have only to escape or conceal yourself for a
while, until the storm has blown over! I well recollect the time when
thieves and murderers of Indians fled from impending punishment
across the Susquehannah, where they considered themselves safe;
on which account this river had the name given to it of “the rogue’s
river.” I have heard other rivers called by similar names.
In the year 1742, the Reverend Mr. Whitefield offered the Nazareth
Manor (as it was then called) for sale to the United Brethren.260 He
had already begun to build upon it a spacious stone house, intended
as a school house for the education of negro children. The Indians,
in the meanwhile, loudly exclaimed against the white people for
settling in this part of the country, which had not yet been legally
purchased of them, but, as they said, had been obtained by
fraud.261 The Brethren declined purchasing any lands on which the
Indian title had not been properly extinguished, wishing to live in
peace with all the Indians around them. Count Zinzendorff happened
at that time to arrive in the country; he found that the agents of the
proprietors would not pay to the Indians the price which they asked
for that tract of land; he paid them out of his private purse the
whole of the demand which they made in the height of their ill
temper, and moreover gave them permission to abide on the land, at
their village, (where, by the by, they had a fine large peach orchard,)
as long as they should think proper. But among those white men,
who afterwards came and settled in the neighbourhood of their
tract, there were some who were enemies to the Indians, and a
young Irishman, without cause or provocation, murdered their good
and highly respected chief Tademi,262 a man of such an easy and
friendly address, that he could not but be loved by all who knew
him. This, together with the threats of other persons, ill disposed
towards them, was the cause of their leaving their settlement on this
manor, and removing to places of greater safety.
But what shall I say of the conduct of the British agents, or deputy
agents, or by whatsoever other name they may be called, who, at
the commencement of the American Revolution, openly excited the
Indians to kill and destroy all the rebels without distinction? “Kill all
the rebels,” they would say, “put them all to death, and spare none.”
A veteran chief of the Wyandot nation, who resided near Detroit,
observed to one of them that surely it was meant that they should
kill men only, and not women and children. “No, no,” was the
answer, “kill all, destroy all; nits breed lice!” The brave veteran263
was so disgusted with this reply, that he refused to go out at all;
wishing however to see and converse with his old brother soldiers of
the Delaware nation, with whom he had fought against the English
in the French war, he took the command of a body of ninety chosen
men, and being arrived at the seat of the government of the
Delawares, on the Muskingum, he freely communicated to his old
comrades (among whom was Glikhican, whom I shall presently have
occasion further to mention) what had taken place, and what he had
resolved on; saying that he never would be guilty of killing women
and children; that this was the first and would be the last of his
going out this war; that in ten days they should see him come back
with one prisoner only, no scalp to a pole, and no life lost. He kept
his word. The sixteen chiefs under him, from respect and principle,
agreed to all his proposals and wishes.
How different the conduct of the Indians from that of their inhuman
employers! I have already related the noble speech of Captain Pipe
to the British Commandant at Detroit, and I have done justice to the
character of that brave officer, who surely ought not to be
confounded with those Indian agents that I have spoken of. But
what said Pipe to him? “Innocence had no part in your quarrels; and
therefore I distinguished—I spared. Father! I hope you will not
destroy what I have saved!”264 I have also told the conduct of the
two young spirited Delawares265 who saved the life of the venerable
Missionary Zeisberger, at the risk of their own. But it is not only
against their own people that Indians have afforded their protection
to white men, but against the whites themselves.
Let us now contrast with this the conduct of the Indians. Carver tells
us in his travels with what moderation, humanity and delicacy they
treat female prisoners, and particularly pregnant women.266 I refer
the reader to the following fact, as an instance of their conduct in
such cases. If his admiration is excited by the behaviour of the
Indians, I doubt not that his indignation will be raised in an equal
degree by that of a white man who unfortunately acts a part in the
story.
Now for the reverse of the picture. Among the men whom this chief
had under his command, was one of those white vagabonds whom I
have before described. The captain was much afraid of him, knowing
him to be a bad man; and as he had expressed a great desire to go
a hunting with the rest, he believed him gone, and entertained no
fears for the woman’s safety. But it was not long before he was
undeceived. While he was gone to a small distance to dig roots for
his poor patient, he heard her cries, and running with speed to her
hut, he was informed by her that the white man had threatened to
take her life if she did not immediately throw her child into the river.
The Captain, enraged at the cruelty of this man, and the liberty he
had taken with his prisoner, hailed him as he was running off, and
told him, “That the moment he should miss the child, the tomahawk
should be in his head.” After a few days this humane chief placed
the woman carefully on a horse, and they went together to the place
of their destination, the mother and child doing well. I have heard
him relate this story, to which he added, that whenever he should go
out on an excursion, he never would suffer a white man to be of his
party.
Yet I must acknowledge that I have known an Indian chief who had
been guilty of the crime of killing the child of a female prisoner. It
was Glikhican,267 of whom I have before spoken, as one of the
friends of the brave Wyandot who expressed so much horror at the
order given to him by the Indian agents to murder women and
children.268 In the year 1770, he joined the congregation of the
Christian Indians; the details of his conversion are related at large by
Loskiel in his History of the Missions.269 Before that time he had
been conspicuous as a warrior and a counsellor, and in oratory it is
said he never was surpassed. This man, having joined the French, in
the year 1754, or 1755, in their war against the English, and being
at that time out with a party of Frenchmen, took, among other
prisoners, a young woman named Rachel Abbott, from the
Conegocheague settlement,270 who had at her breast a sucking
babe. The incessant cries of the child, the hurry to get off, but above
all, the persuasions of his white companions, induced him, much
against his inclination, to kill the innocent creature; while the
mother, in an agony of grief, and her face suffused with tears,
begged that its life might be spared. The woman, however, was
brought safe to the Ohio, where she was kindly treated and adopted,
and some years afterwards was married to a Delaware chief of
respectability, by whom she had several children, who are now living
with the Christian Indians in Upper Canada.
The Indians are cruel to their enemies! In some cases they are, but
perhaps not more so than white men have sometimes shewn
themselves. There have been instances of white men flaying or
taking off the skin of Indians who had fallen into their hands, then
tanning those skins, or cutting them in pieces, making them up into
razor-straps, and exposing those for sale, as was done at or near
Pittsburg sometime during the Revolutionary war. Those things are
abominations in the eyes of the Indians, who, indeed, when strongly
excited, inflict torments on their prisoners and put them to death by
cruel tortures, but never are guilty of acts of barbarity in cold blood.
Neither do the Delawares and some other Indian nations, ever on
any account disturb the ashes of the dead.
But if the Indians, after all, are really those horrid monsters which
they are alleged to be, two solemn, serious questions have often
occurred to my mind, to which I wish the partisans of that doctrine
would give equally serious answers.
I still indulge the hope that this work will be accomplished by a wise
and benevolent government. Thus we shall demonstrate the falsity
of the prediction of the Indian prophets, who say: “That when the
whites shall have ceased killing the red men, and got all their lands
from them, the great tortoise which bears this island upon his back,
shall dive down into the deep and drown them all, as he once did
before, a great many years ago; and that when he again rises, the
Indians shall once more be put in possession of the whole country.”
CONCLUSION.
HAVE thus finished the work which was required of me by
the Historical Committee of the American Philosophical
Society. On reading over the printed sheets which have
been kindly sent to me from Philadelphia, as they issued from the
press, I have noticed several errors, some of which may be ascribed
to me, others to the transcriber of the manuscript, and very few to
the printer. I regret that there are among them some mistakes in
dates and names of places; they are all rectified in the errata.
It is with pleasure that I inform the reader that the parts of Mr.
Zeisberger’s Iroquois Dictionary which I have mentioned above,
(pages 97, 118,) as being irretrievably lost, have most fortunately
been found since this work is in the press. The book has been neatly
bound in seven quarto volumes, and will remain a monument of the
richness and comprehensiveness of the languages of the Indian
nations. Several valuable grammatical works on the same language,
by the same author and Mr. Pyrlæus, have been recovered at the
same time, by means of which, the idiom of the Six Nations may
now be scientifically studied.
When I spoke (p. 136) of the impression made by Captain Pipe’s
speech “on all present,” I meant only on those who understood the
language; for there were many who did not, and M. Baby, the
Canadian interpreter, did not explain to the bystanders the most
striking passages, but went now and then to the Commandant and
whispered in his ear. Captain Pipe, while he spoke, was exceedingly
animated, and twice advanced so near to the Commandant, that M.
Baby ordered him to fall back to his place. All who were present
must have at least suspected that his speech was not one of the
ordinary kind, and that everything was not as they might suppose it
ought to be.
CORRESPONDENCE
BETWEEN
THE REV. JOHN HECKEWELDER.
OF BETHLEHEM,
AND
RESPECTING THE
This MS. being written in German, was not intelligible to the greatest
number of the members. Two of them, the Reverend Dr. Nicholas
Collin, and the corresponding secretary, were particularly anxious to
be honoured with the task of translating it; but the secretary having
claimed this labour as part of his official duty, it was adjudged to
him. While he was translating that work, he was struck with the
beauty of the grammatical forms of the Lenape idiom, which led him
to ask through Dr. Wistar some questions of Mr. Heckewelder,271
which occurred to him as he was pursuing his labours, and produced
the correspondence now published, which was carried on by the
direction and under the sanction of the Committee.
The letters which passed at the beginning between Dr. Wistar and
Mr. Zeisberger,272 and are here published in their regular order, do
not, it is true, form a necessary part of this collection; but it will be
perceived, that to the two letters of Dr. Wistar, Nos. 2 and 6, we are
indebted for the valuable Historical Account of the Indians, which
forms the first number of this volume. It is just that he should have
the credit due to his active and zealous exertions.
LETTER I.
MR. DUPONCEAU TO MR. HECKEWELDER.
Our website is not just a platform for buying books, but a bridge
connecting readers to the timeless values of culture and wisdom. With
an elegant, user-friendly interface and an intelligent search system,
we are committed to providing a quick and convenient shopping
experience. Additionally, our special promotions and home delivery
services ensure that you save time and fully enjoy the joy of reading.
ebookultra.com