The files `g++-include/List.hP' and `g++-include/List.ccP'
provide pseudo-generic Lisp-type List classes. These lists are homogeneous
lists, more similar to lists in statically typed functional languages like
ML than Lisp, but support operations very similar to those found in Lisp.
Any particular kind of list class may be generated via the genclass
shell command. However, the implementation assumes that the base class
supports an equality operator ==
. All equality tests use the
==
operator, and are thus equivalent to the use of equal
, not
eq
in Lisp.
All list nodes are created dynamically, and managed via reference counts.
List
variables are actually pointers to these list nodes.
Lists may also be traversed via Pixes, as described in the section
describing Pixes. See section Pseudo-indexes
Supported operations are mirrored closely after those in Lisp. Generally, operations with functional forms are constructive, functional operations, while member forms (often with the same name) are sometimes procedural, possibly destructive operations.
As with Lisp, destructive operations are supported. Programmers are allowed to change head and tail fields in any fashion, creating circular structures and the like. However, again as with Lisp, some operations implicitly assume that they are operating on pure lists, and may enter infinite loops when presented with improper lists. Also, the reference-counting storage management facility may fail to reclaim unused circularly-linked nodes.
Several Lisp-like higher order functions are supported (e.g., map
).
Typedef declarations for the required functional forms are provided
int the `.h' file.
For purposes of illustration, assume the specification of class
intList
. Common Lisp versions of supported operations are shown
in brackets for comparison purposes.
intList a; [ (setq a nil) ]
intList b(2); [ (setq b (cons 2 nil)) ]
intList c(3, b); [ (setq c (cons 3 b)) ]
b = a; [ (setq b a) ]
Assume the declarations of intLists a, b, and c in the following. See section Pseudo-indexes.
a.null(); OR !a; [ (null a) ]
a.valid(); [ (listp a) ]
void*
coercion may also be used as in if (a) ...
.
intList(); [ nil ]
intList f(int x) {if (x == 0) return intList(); ... }
.
a.length(); [ (length a) ]
a.list_length(); [ (list-length a) ]
a.get(); OR a.head() [ (car a) ]
a[2]; [ (elt a 2) ]
a.tail(); [ (cdr a) ]
a.last(); [ (last a) ]
a.nth(2); [ (nth a 2) ]
a.set_tail(b); [ (rplacd a b) ]
a.push(2); [ (push 2 a) ]
int x = a.pop() [ (setq x (car a)) (pop a) ]
b = copy(a); [ (setq b (copy-seq a)) ]
b = reverse(a); [ (setq b (reverse a)) ]
c = concat(a, b); [ (setq c (concat a b)) ]
c = append(a, b); [ (setq c (append a b)) ]
b = map(f, a); [ (setq b (mapcar f a)) ]
c = combine(f, a, b);
b = remove(x, a); [ (setq b (remove x a)) ]
b = remove(f, a); [ (setq b (remove-if f a)) ]
b = select(f, a); [ (setq b (remove-if-not f a)) ]
c = merge(a, b, f); [ (setq c (merge a b f)) ]
a.append(b); [ (rplacd (last a) b) ]
a.prepend(b); [ (setq a (append b a)) ]
a.del(x); [ (delete x a) ]
a.del(f); [ (delete-if f a) ]
a.select(f); [ (delete-if-not f a) ]
a.reverse(); [ (nreverse a) ]
a.sort(f); [ (sort a f) ]
a.apply(f); [ (mapc f a) ]
a.subst(int old, int repl); [ (nsubst repl old a) ]
a.find(int x); [ (find x a) ]
a.find(b); [ (find b a) ]
a.contains(int x); [ (member x a) ]
a.contains(b); [ (member b a) ]
a.position(int x); [ (position x a) ]
int x = a.reduce(f, int base); [ (reduce f a :initial-value base) ]