------------------------------------------------------------------------------
MC logo
Toms Lisp Lists
[^] Tom's Lisp
------------------------------------------------------------------------------
[Basic Input Format] [Lists, Pairs and Related Operations] [Conditional Evaluation] [Basic Function Definition] [Definitions and Scope] [Functions Which Take Functions] [String Functions] [Exception Handling] [Quoting And Evaluation] [Variable-Length Parameter Lists] [Macro Definitions] [Printing] [The Tomslsp command and its switches] [Index of Standard Functions]

Tom's Lisp types already mentioned include integers, strings and identifiers. There are also closures, macros and errors, which are covered in later sections. Here, we discuss the list structure, which gives Lisp much of its flexibility and character.

A list is just a series of other data items (any of which may also be lists) separated by spaces and surrounded by parentheses. Lisp function calls are lists, so if you enter a list without using a tick, Tom's Lisp will attempt to evaluate it as a function call.

lsp>(+ 4 5 6)
15
lsp>'(+ 4 5 6)
(+ 4 5 6)
lsp>'(hi there 17 "frank")
(hi there 17 "frank")
lsp>(hi there 17 "frank")
**** Error 1: Undefined hi ****
   (hi there 17 "frank")
lsp>'(45 (3 4 22 "zzz") (4 (8 9) 4 3)))
(45 (3 4 22 "zzz") (4 (8 9) 4 3))

The basic operations on lists are car, cdr and cons. The car operation returns the head (first member) of the list. The cdr returns the balance of the list after the first item. The cons operation takes an item and a list and adds the item to front of the list.

lsp>(car '(a b c))
a
lsp>(cdr '(a b c))
(b c)
lsp>(cons 'fred '(a b c))
(fred a b c)
lsp>(cons (car '(x y z)) (cdr '(x y z)))
(x y z)

Each operation works on its arguments and computes and returns a new list. Tom's Lisp never updates an existing list. It always creates and returns a new list. The unintuitive names car and cdr are historic. (Translation: It's the way we've always done it, and it too much trouble to change.)

The empty list is (), but it also goes by the names nil and #f, the later indicating “false”

lsp>() 
nil
lsp>nil
nil
lsp>(cons 17 nil)      
(17)

There are several abbreviations useful when repeatedly using car and cdr. For instance,

lsp>(cadr '(a b c d))
b
lsp>(caddr '(a b c d))
c
lsp>(cdadr '((a b c) (1 2 3) (time to go))))
(2 3)
These are useful when you wish to pick something out of a complex structure involving lists of lists.

There is also a useful utility which simply makes a list out of its arguments.

lsp>(list 8 'now "goo" 13)
(8 now "goo" 13)

Car, cons and cdr are the fundamental list operations. Any list can be built or examined with these. As most lisps, though, Tom's Lisp does add a few extras for convenience:
lengthReturn the length of a list.
appendAppend two or more lists together.
firstTakes an integer n and a list l, and returns the first n items of list l.
lastTakes an integer n and a list l, and returns the last n items of list l.
first-butTakes an integer n and a list l, and returns l, omitting the first n items.
last-butTakes an integer n and a list l, and returns l, omitting the last n items.
nthTakes an integer n and a list l, and returns the nth member of l, counting from zero.
If the list is too small to contain the requested portion, you get the empty list back.

lsp>(length '(a b c))
3
lsp>(length '(a (b c) (d e f) (g h i)))
4
lsp>(length ())
0
lsp>(append '(a b c) '(d e))
(a b c d e)
lsp>(append '(a b (c d)) '(e f g) '(h (i j k)))
(a b (c d) e f g h (i j k))
lsp>(first 3 '(a b c d e f g))
(a b c)
lsp>(last 2 '(1 9 8 13 99))
(13 99)
lsp>(first-but 2 '(1 9 8 13 99))
(8 13 99)
lsp>(last-but 3 '(this that left right up down over))
(this that left right)
lsp>(nth 3 '(3 4 9 1 sam 17 4))
1

Pairs

Lists are actually based on a more basic type, the dotted pair. A dotted pair is represented as two items separated by a dot.
lsp>(a . b)
(a . b)
lsp>'((7 . 12) . 34)
((7 . 12) . 34)'

Lists are built with pairs. For instance, the list

(1 2 3 4)
is an abbreviation for
(1 . (2 . (3 . (4 . nil))))
For instance:
lsp>(1 . (2 . (3 . (4 . ()))))
(1 2 3 4)'
The system prints values in list notation when possible, otherwise it uses dotted notation.
lsp>((5 . (goop . drip)) . (99 . 100))
((5 goop . drip) 99 . 100)'

The pair is the result of cons, and the car and cdr operations extract the first and second item from the pair.

lsp>(car '(7 . 5))
7
lsp>(cdr '(this . that))
that
lsp>(cons 12 14)
(12 . 14)
lsp>(cons 'yes (cons 'no (cons 'maybe nil)))
(yes no maybe)
This is consistent with the list meaning.
lsp>'(a . (b . ()))
(a b)
lsp>(cdr '(a . (b . ())))
(b)
lsp>'(b . ()) 
(b)