[ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
[ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
This section enumerates some of the various different primitive types of objects in Zetalisp. The types explained below include symbols, conses, various types of numbers, two kinds of compiled code objects, locatives, arrays, stack groups, and closures. With each is given the associated symbolic name, which is returned by the function data-type ((data-type-fun)).
A symbol (these are sometimes called "atoms" or "atomic symbols" by other texts) has a print name, a binding, a definition, a property list, and a package.
The print name is a string, which may be obtained by the function get-pname ((get-pname-fun)). This string serves as the printed representation (see (printer)) of the symbol. Each symbol has a binding (sometimes also called the "value"), which may be any Lisp object. It is also referred to sometimes as the "contents of the value cell", since internally every symbol has a cell called the value cell which holds the binding. It is accessed by the symeval function ((symeval-fun)), and updated by the set function ((set-fun)). (That is, given a symbol, you use symeval to find out what its binding is, and use set to change its binding.) Each symbol has a definition, which may also be any Lisp object. It is also referred to as the "contents of the function cell", since internally every symbol has a cell called the function cell which holds the definition. The definition can be accessed by the fsymeval function ((fsymeval-fun)), and updated with fset ((fset-fun)), although usually the functions fdefinition and fdefine are employed ((fdefine-fun)). The property list is a list of an even number of elements; it can be accessed directly by plist ((plist-fun)), and updated directly by setplist ((setplist-fun)), although usually the functions get, putprop, and remprop ((get-fun)) are used. The property list is used to associate any number of additional attributes with a symbol--attributes not used frequently enough to deserve their own cells as the value and definition do. Symbols also have a package cell, which indicates which "package" of names the symbol belongs to. This is explained further in the section on packages (chapter (package-chapter)) and can be disregarded by the casual user.
The primitive function for creating symbols is make-symbol ((make-symbol-fun)), although most symbols are created by read, intern, or fasload (which call make-symbol themselves.)
A cons is an object that cares about two other objects, arbitrarily named the car and the cdr. These objects can be accessed with car and cdr ((car-fun)), and updated with rplaca and rplacd ((rplaca-fun)). The primitive function for creating conses is cons ((cons-fun)).
There are several kinds of numbers in Zetalisp. Fixnums represent integers in the range of -2^23 to 2^23-1. Bignums represent integers of arbitrary size, but they are more expensive to use than fixnums because they occupy storage and are slower. The system automatically converts between fixnums and bignums as required. Flonums are floating-point numbers. Small-flonums are another kind of floating-point numbers, with less range and precision, but less computational overhead. Other types of numbers are likely to be added in the future. See (number) for full details of these types and the conversions between them.
The usual form of compiled, executable code is a Lisp object called a "Function Entry Frame" or "FEF". A FEF contains the code for one function. This is analogous to what Maclisp calls a "subr pointer". FEFs are produced by the Lisp Compiler ((compiler)), and are usually found as the definitions of symbols. The printed representation of a FEF includes its name, so that it can be identified. Another Lisp object which represents executable code is a "micro-code entry". These are the microcoded primitive functions of the Lisp system, and user functions compiled into microcode.
About the only useful thing to do with any of these compiled code objects is to apply it to arguments. However, some functions are provided for examining such objects, for user convenience. See arglist ((arglist-fun)), args-info ((args-info-fun)), describe ((describe-fun)), and disassemble ((disassemble-fun)).
A locative (see (locative)) is a kind of a pointer to a single memory cell anywhere in the system. The contents of this cell can be accessed by cdr (see (cdr-fun)) and updated by rplacd (see (rplacd-fun)).
An array (see (array)) is a set of cells indexed by a tuple of integer subscripts. The contents of the cells may be accessed and changed individually. There are several types of arrays. Some have cells which may contain any object, while others (numeric arrays) may only contain small positive numbers. Strings are a type of array; the elements are 8-bit unsigned numbers which encode characters.
A list is not a primitive data type, but rather a data structure made up out of conses and the symbol nil. See (list-and-tree).
[ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
By convention, the names of predicates usually end in the letter "p" (which stands for "predicate").
The following predicates are for testing data types. These predicates return t if the argument is of the type indicated by the name of the function, nil if it is of some other type.
The symbols that can be returned by typep of one argument are:
:symbol
:fixnum
:bignum
:flonum
:small-flonum
:list
:locative
:compiled-function
:microcode-function
:closure
:select-method
:stack-group
:string
:array
:random
foo
The type argument to typep of two arguments can be any of the above keyword symbols (except for :random), the name of a user-defined data type (either a named structure or a flavor), or one of the following additional symbols:
:atom
:fix
:float
:number
:instance
:entity
See also data-type, (data-type-fun).
Note that (typep nil) => :symbol, and (typep nil ':list) => nil; the latter may be changed.
The following functions are some other general purpose predicates.
Examples: (eq 'a 'b) => nil (eq 'a 'a) => t (eq (cons 'a 'b) (cons 'a 'b)) => nil (setq x (cons 'a 'b)) (eq x x) => t |
(defun equal (x y) (cond ((eq x y) t) ((neq (typep x) (typep y)) nil) ((numberp x) (= x y)) ((stringp x) (string-equal x y)) ((listp x) (and (equal (car x) (car y)) (equal (cdr x) (cdr y)))))) |
As a consequence of the above definition, it can be seen that equal may compute forever when applied to looped list structure. In addition, eq always implies equal; that is, if (eq a b) then (equal a b). An intuitive definition of equal (which is not quite correct) is that two objects are equal if they look the same when printed out. For example:
(setq a '(1 2 3)) (setq b '(1 2 3)) (eq a b) => nil (equal a b) => t (equal "Foo" "foo") => t |
(cond ((not (null lst)) ... ) ( ... )) rather than (cond (lst ... ) ( ... )) |
[ << ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |