Next: How Lisp Objects Are Represented in C, Previous: SXEmacs From the Inside, Up: Top [Contents][Index]
At the heart of the Lisp interpreter is its management of objects.
SXEmacs Lisp contains many built-in objects, some of which are
simple and others of which can be very complex; and some of which
are very common, and others of which are rarely used or are only
used internally. (Since the Lisp allocation system, with its
automatic reclamation of unused storage, is so much more convenient
than malloc()
and free()
, the C code makes extensive use of it
in its internal operations.)
The basic Lisp objects are
integer
28 or 31 bits of precision, or 60 or 63 bits on 64-bit machines; the reason for this is described below when the internal Lisp object representation is described.
float
Same precision as a double in C.
cons
A simple container for two Lisp objects, used to implement lists and most other data structures in Lisp.
char
An object representing a single character of text; chars behave like
integers in many ways but are logically considered text rather than
numbers and have a different read syntax. (the read syntax for a char
contains the char itself or some textual encoding of it—for example,
a Japanese Kanji character might be encoded as ‘^[$(B#&^[(B’ using the
ISO-2022 encoding standard—rather than the numerical representation
of the char; this way, if the mapping between chars and integers
changes, which is quite possible for Kanji characters and other extended
characters, the same character will still be created. Note that some
primitives confuse chars and integers. The worst culprit is eq
,
which makes a special exception and considers a char to be eq
to
its integer equivalent, even though in no other case are objects of two
different types eq
. The reason for this monstrosity is
compatibility with existing code; the separation of char from integer
came fairly recently.)
symbol
An object that contains Lisp objects and is referred to by name; symbols are used to implement variables and named functions and to provide the equivalent of preprocessor constants in C.
vector
A one-dimensional array of Lisp objects providing constant-time access to any of the objects; access to an arbitrary object in a vector is faster than for lists, but the operations that can be done on a vector are more limited.
string
Self-explanatory; behaves much like a vector of chars but has a different read syntax and is stored and manipulated more compactly.
bit-vector
A vector of bits; similar to a string in spirit.
compiled-function
An object containing compiled Lisp code, known as byte code.
subr
A Lisp primitive, i.e. a Lisp-callable function implemented in C.
Note that there is no basic “function” type, as in more powerful
versions of Lisp (where it’s called a closure). SXEmacs Lisp does
not provide the closure semantics implemented by Common Lisp and Scheme.
The guts of a function in SXEmacs Lisp are represented in one of four
ways: a symbol specifying another function (when one function is an
alias for another), a list (whose first element must be the symbol
lambda
) containing the function’s source code, a
compiled-function object, or a subr object. (In other words, given a
symbol specifying the name of a function, calling symbol-function
to retrieve the contents of the symbol’s function cell will return one
of these types of objects.)
SXEmacs Lisp also contains numerous specialized objects used to implement the editor:
buffer
Stores text like a string, but is optimized for insertion and deletion and has certain other properties that can be set.
frame
An object with various properties whose displayable representation is a window in window-system parlance.
window
A section of a frame that displays the contents of a buffer; often called a pane in window-system parlance.
window-configuration
An object that represents a saved configuration of windows in a frame.
device
An object representing a screen on which frames can be displayed; equivalent to a display in the X Window System and a TTY in character mode.
face
An object specifying the appearance of text or graphics; it has properties such as font, foreground color, and background color.
marker
An object that refers to a particular position in a buffer and moves around as text is inserted and deleted to stay in the same relative position to the text around it.
extent
Similar to a marker but covers a range of text in a buffer; can also specify properties of the text, such as a face in which the text is to be displayed, whether the text is invisible or unmodifiable, etc.
event
Generated by calling next-event
and contains information
describing a particular event happening in the system, such as the user
pressing a key or a process terminating.
keymap
An object that maps from events (described using lists, vectors, and symbols rather than with an event object because the mapping is for classes of events, rather than individual events) to functions to execute or other events to recursively look up; the functions are described by name, using a symbol, or using lists to specify the function’s code.
glyph
An object that describes the appearance of an image (e.g. pixmap) on the screen; glyphs can be attached to the beginning or end of extents and in some future version of SXEmacs will be able to be inserted directly into a buffer.
process
An object that describes a connection to an externally-running process.
There are some other, less-commonly-encountered general objects:
hash-table
An object that maps from an arbitrary Lisp object to another arbitrary Lisp object, using hashing for fast lookup.
obarray
A limited form of hash-table that maps from strings to symbols; obarrays are used to look up a symbol given its name and are not actually their own object type but are kludgily represented using vectors with hidden fields (this representation derives from GNU Emacs).
specifier
A complex object used to specify the value of a display property; a default value is given and different values can be specified for particular frames, buffers, windows, devices, or classes of device.
char-table
An object that maps from chars or classes of chars to arbitrary Lisp objects; internally char tables use a complex nested-vector representation that is optimized to the way characters are represented as integers.
range-table
An object that maps from ranges of integers to arbitrary Lisp objects.
And some strange special-purpose objects:
charset
coding-system
Objects used when MULE, or multi-lingual/Asian-language, support is enabled.
color-instance
font-instance
image-instance
An object that encapsulates a window-system resource; instances are mostly used internally but are exposed on the Lisp level for cleanness of the specifier model and because it’s occasionally useful for Lisp program to create or query the properties of instances.
subwindow
An object that encapsulate a subwindow resource, i.e. a window-system child window that is drawn into by an external process; this object should be integrated into the glyph system but isn’t yet, and may change form when this is done.
toolbar-button
An object used in conjunction with the toolbar.
And objects that are only used internally:
opaque
A generic object for encapsulating arbitrary memory; this allows you the
generality of malloc()
and the convenience of the Lisp object
system.
lstream
A buffering I/O stream, used to provide a unified interface to anything that can accept output or provide input, such as a file descriptor, a stdio stream, a chunk of memory, a Lisp buffer, a Lisp string, etc.; it’s a Lisp object to make its memory management more convenient.
char-table-entry
Subsidiary objects in the internal char-table representation.
extent-auxiliary
menubar-data
toolbar-data
Various special-purpose objects that are basically just used to encapsulate memory for particular subsystems, similar to the more general “opaque” object.
symbol-value-forward
symbol-value-buffer-local
symbol-value-varalias
symbol-value-lisp-magic
Special internal-only objects that are placed in the value cell of a symbol to indicate that there is something special with this variable – e.g. it has no value, it mirrors another variable, or it mirrors some C variable; there is really only one kind of object, called a symbol-value-magic, but it is sort-of halfway kludged into semi-different object types.
Some types of objects are permanent, meaning that once created,
they do not disappear until explicitly destroyed, using a function such
as delete-buffer
, delete-window
, delete-frame
, etc.
Others will disappear once they are not longer used, through the garbage
collection mechanism. Buffers, frames, windows, devices, and processes
are among the objects that are permanent. Note that some objects can go
both ways: Faces can be created either way; extents are normally
permanent, but detached extents (extents not referring to any text, as
happens to some extents when the text they are referring to is deleted)
are temporary. Note that some permanent objects, such as faces and
coding systems, cannot be deleted. Note also that windows are unique in
that they can be undeleted after having previously been
deleted. (This happens as a result of restoring a window configuration.)
Note that many types of objects have a read syntax, i.e. a way of
specifying an object of that type in Lisp code. When you load a Lisp
file, or type in code to be evaluated, what really happens is that the
function read
is called, which reads some text and creates an object
based on the syntax of that text; then eval
is called, which
possibly does something special; then this loop repeats until there’s
no more text to read. (eval
only actually does something special
with symbols, which causes the symbol’s value to be returned,
similar to referencing a variable; and with conses [i.e. lists],
which cause a function invocation. All other values are returned
unchanged.)
The read syntax
17297
converts to an integer whose value is 17297.
1.983e-4
converts to a float whose value is 1.983e-4, or .0001983.
?b
converts to a char that represents the lowercase letter b.
?^[$(B#&^[(B
(where ‘^[’ actually is an ‘ESC’ character) converts to a particular Kanji character when using an ISO2022-based coding system for input. (To decode this goo: ‘ESC’ begins an escape sequence; ‘ESC $ (’ is a class of escape sequences meaning “switch to a 94x94 character set”; ‘ESC $ ( B’ means “switch to Japanese Kanji”; ‘#’ and ‘&’ collectively index into a 94-by-94 array of characters [subtract 33 from the ASCII value of each character to get the corresponding index]; ‘ESC (’ is a class of escape sequences meaning “switch to a 94 character set”; ‘ESC (B’ means “switch to US ASCII”. It is a coincidence that the letter ‘B’ is used to denote both Japanese Kanji and US ASCII. If the first ‘B’ were replaced with an ‘A’, you’d be requesting a Chinese Hanzi character from the GB2312 character set.)
"foobar"
converts to a string.
foobar
converts to a symbol whose name is "foobar"
. This is done by
looking up the string equivalent in the global variable
obarray
, whose contents should be an obarray. If no symbol
is found, a new symbol with the name "foobar"
is automatically
created and added to obarray
; this process is called
interning the symbol.
(foo . bar)
converts to a cons cell containing the symbols foo
and bar
.
(1 a 2.5)
converts to a three-element list containing the specified objects (note that a list is actually a set of nested conses; see the SXEmacs Lisp Reference).
[1 a 2.5]
converts to a three-element vector containing the specified objects.
#[... ... ... ...]
converts to a compiled-function object (the actual contents are not shown since they are not relevant here; look at a file that ends with .elc for examples).
#*01110110
converts to a bit-vector.
#s(hash-table ... ...)
converts to a hash table (the actual contents are not shown).
#s(range-table ... ...)
converts to a range table (the actual contents are not shown).
#s(char-table ... ...)
converts to a char table (the actual contents are not shown).
Note that the #s()
syntax is the general syntax for structures,
which are not really implemented in SXEmacs Lisp but should be.
When an object is printed out (using print
or a related
function), the read syntax is used, so that the same object can be read
in again.
The other objects do not have read syntaxes, usually because it does not really make sense to create them in this fashion (i.e. processes, where it doesn’t make sense to have a subprocess created as a side effect of reading some Lisp code), or because they can’t be created at all (e.g. subrs). Permanent objects, as a rule, do not have a read syntax; nor do most complex objects, which contain too much state to be easily initialized through a read syntax.
Next: How Lisp Objects Are Represented in C, Previous: SXEmacs From the Inside, Up: Top [Contents][Index]