6.6.8 Pairs

Pairs are used to combine two Scheme objects into one compound object. Hence the name: A pair stores a pair of objects.

The data type pair is extremely important in Scheme, just like in any other Lisp dialect. The reason is that pairs are not only used to make two values available as one object, but that pairs are used for constructing lists of values. Because lists are so important in Scheme, they are described in a section of their own (see Lists).

Pairs can literally get entered in source code or at the REPL, in the so-called dotted list syntax. This syntax consists of an opening parentheses, the first element of the pair, a dot, the second element and a closing parentheses. The following example shows how a pair consisting of the two numbers 1 and 2, and a pair containing the symbols foo and bar can be entered. It is very important to write the whitespace before and after the dot, because otherwise the Scheme parser would not be able to figure out where to split the tokens.

(1 . 2)
(foo . bar)

But beware, if you want to try out these examples, you have to quote the expressions. More information about quotation is available in the section Expression Syntax. The correct way to try these examples is as follows.

'(1 . 2)
⇒
(1 . 2)
'(foo . bar)
⇒
(foo . bar)

A new pair is made by calling the procedure cons with two arguments. Then the argument values are stored into a newly allocated pair, and the pair is returned. The name cons stands for "construct". Use the procedure pair? to test whether a given Scheme object is a pair or not.

Scheme Procedure: cons x y
C Function: scm_cons (x, y)

Return a newly allocated pair whose car is x and whose cdr is y. The pair is guaranteed to be different (in the sense of eq?) from every previously existing object.

Scheme Procedure: pair? x
C Function: scm_pair_p (x)

Return #t if x is a pair; otherwise return #f.

C Function: int scm_is_pair (SCM x)

Return 1 when x is a pair; otherwise return 0.

The two parts of a pair are traditionally called car and cdr. They can be retrieved with procedures of the same name (car and cdr), and can be modified with the procedures set-car! and set-cdr!.

Since a very common operation in Scheme programs is to access the car of a car of a pair, or the car of the cdr of a pair, etc., the procedures called caar, cadr and so on are also predefined. However, using these procedures is often detrimental to readability, and error-prone. Thus, accessing the contents of a list is usually better achieved using pattern matching techniques (see Pattern Matching).

Scheme Procedure: car pair
Scheme Procedure: cdr pair
C Function: scm_car (pair)
C Function: scm_cdr (pair)

Return the car or the cdr of pair, respectively.

C Macro: SCM SCM_CAR (SCM pair)
C Macro: SCM SCM_CDR (SCM pair)

These two macros are the fastest way to access the car or cdr of a pair; they can be thought of as compiling into a single memory reference.

These macros do no checking at all. The argument pair must be a valid pair.

Scheme Procedure: cddr pair
Scheme Procedure: cdar pair
Scheme Procedure: cadr pair
Scheme Procedure: caar pair
Scheme Procedure: cdddr pair
Scheme Procedure: cddar pair
Scheme Procedure: cdadr pair
Scheme Procedure: cdaar pair
Scheme Procedure: caddr pair
Scheme Procedure: cadar pair
Scheme Procedure: caadr pair
Scheme Procedure: caaar pair
Scheme Procedure: cddddr pair
Scheme Procedure: cdddar pair
Scheme Procedure: cddadr pair
Scheme Procedure: cddaar pair
Scheme Procedure: cdaddr pair
Scheme Procedure: cdadar pair
Scheme Procedure: cdaadr pair
Scheme Procedure: cdaaar pair
Scheme Procedure: cadddr pair
Scheme Procedure: caddar pair
Scheme Procedure: cadadr pair
Scheme Procedure: cadaar pair
Scheme Procedure: caaddr pair
Scheme Procedure: caadar pair
Scheme Procedure: caaadr pair
Scheme Procedure: caaaar pair
C Function: scm_cddr (pair)
C Function: scm_cdar (pair)
C Function: scm_cadr (pair)
C Function: scm_caar (pair)
C Function: scm_cdddr (pair)
C Function: scm_cddar (pair)
C Function: scm_cdadr (pair)
C Function: scm_cdaar (pair)
C Function: scm_caddr (pair)
C Function: scm_cadar (pair)
C Function: scm_caadr (pair)
C Function: scm_caaar (pair)
C Function: scm_cddddr (pair)
C Function: scm_cdddar (pair)
C Function: scm_cddadr (pair)
C Function: scm_cddaar (pair)
C Function: scm_cdaddr (pair)
C Function: scm_cdadar (pair)
C Function: scm_cdaadr (pair)
C Function: scm_cdaaar (pair)
C Function: scm_cadddr (pair)
C Function: scm_caddar (pair)
C Function: scm_cadadr (pair)
C Function: scm_cadaar (pair)
C Function: scm_caaddr (pair)
C Function: scm_caadar (pair)
C Function: scm_caaadr (pair)
C Function: scm_caaaar (pair)

These procedures are compositions of car and cdr, where for example caddr could be defined by

(define caddr (lambda (x) (car (cdr (cdr x)))))

cadr, caddr and cadddr pick out the second, third or fourth elements of a list, respectively. SRFI-1 provides the same under the names second, third and fourth (see Selectors).

Scheme Procedure: set-car! pair value
C Function: scm_set_car_x (pair, value)

Stores value in the car field of pair. The value returned by set-car! is unspecified.

Scheme Procedure: set-cdr! pair value
C Function: scm_set_cdr_x (pair, value)

Stores value in the cdr field of pair. The value returned by set-cdr! is unspecified.