REDUCE

5.2 Basic Functions on Pairs

The following are elementary functions on pairs. All functions in this Chapter which require pairs as parameters signal a type mismatch error if the parameter given is not a pair.

(cons U:any V:any): pair expr
Returns a pair which is not eq to anything else and has U as its car part and V as its cdr part.

(car U:pair): any open-compiled expr
The left part of the pair U is returned. Note that applications of car are open compiled, a compiled application of car will not verify that its argument is a pair. The function SafeCar may be used in place of car. The definitions of these two functions are identical, the difference between them is that safecar is not open compiled. For interpreted applications, the car of nil is nil and if U is something other that a pair or nil the following error will result.
⋆⋆⋆⋆⋆  An attempt was made to do CAR on ‘U', which is not a pair

(cdr U:pair): any open-compiled expr
The left part of the pair U is returned. Note that applications of cdr are open compiled, a compiled application of cdr will not verify that its argument is a pair. The function SafeCdr may be used in place of cdr. The definitions of these two functions are identical, the difference between them is that safecdr is not open compiled. For interpreted applications, the cdr of nil is nil and if U is something other that a pair or nil the following error will result.
⋆⋆⋆⋆⋆ An attempt was made to do CDR on ‘U', which is not a pair

The composites of car and cdr are supported up to four levels.

              Car                             Cdr  
      Caar            Cdar            Cadr            Cddr  
  Caaar  Cdaar    Cadar  Cddar    Caadr  Cdadr    Caddr  Cdddr  
 Caaaar  Cadaar  Caadar  Caddar  Caaadr  Cadadr  Caaddr  Cadddr  
 Cdaaar  Cddaar  Cdadar  Cdddar  Cdaadr  Cddadr  Cdaddr  Cddddr

These are all exprs of one argument. Applications of these functions are generally open compiled. An example of their use is that (cddar p) is equivalent to (cdr (cdr (car p))). For interpreted applications, a type mismatch error occurs if the argument does not possess the specified component.

As an alternative to employing chains of car and cdr to obscure depths, particularly in extracting elements of a list, consider the use of the functions first, second, third, fourth, rest, nth, and pnth.

(ncons U:any): pair expr
Equivalent to (cons u nil).

(xcons LEFT:any RIGHT:any): pair expr
Equivalent to (cons RIGHT LEFT), this function is useful for generating efficient list building code for the compiler.

(copy X:any): any expr
This function returns a copy of X. While each pair is copied, atomic elements (for example ids, strings, and vectors) are not. See totalcopy in section 7.5. Note that copy is recursive and will not terminate if its argument is a circular list.
    (de copy (u)  
      (if (pairp u)  
        (cons (copy (car u)) (copy (cdr u)))  
        u))

    1 lisp> (setq p '("AKU" (charlie)))  
    ("AKU" (CHARLIE))  
    2 lisp> (setq q (copy p))  
    ("AKU" (CHARLIE))  
    3 lisp> (eq p q)  
    NIL  
    4 lisp> (eq (first p) (first q))  
    T  
    5 lisp> (eq (third p) (third q))  
    NIL

See Chapter 6 for other relevant functions.

The following functions are known as ”destructive” functions, because they change the structure of the pair given as their argument, and consequently change the structure of any object containing the pair. They are frequently used to make code more efficient. For example append will copy its first argument whereas nconc will not. These functions are also used to build structures which share sub-structure. It is possible to create self referential structures with these functions. This can create havoc with normal printing and list traversal functions.

(rplaca U:pair V:any): pair open-compiled expr
The car of the pair U is replaced by V, the modified pair U is returned. A type mismatch error occurs if U is not a pair
    1 lisp> (setq fruit '(orange apple))  
    (ORANGE APPLE)  
    2 lisp> (setq food (cons 'cheese fruit))  
    (CHEESE ORANGE APPLE)  
    3 lisp> (rplaca fruit 'peach)  
    (PEACH APPLE)  
    4 lisp> food  
    (CHEESE PEACH APPLE)

(rplacd U:pair V:any): pair open-compiled expr
The cdr of the pair U is replaced by V, the modified pair U is returned. A type mismatch error occurs if U is not a pair.
    1 lisp> (setq pair '(left))  
    (LEFT)  
    2 lisp> (progn (rplacd pair 'right) pair)  
    (LEFT . RIGHT)

(rplacw A:pair B:pair): pair expr
Replaces the whole pair: the car of A is replaced with the car of B, and the cdr of A with the cdr of B. The modified pair A is returned.