Next: , Previous: Weak References, Up: Weak References

#### 10.7.1 Weak Pairs

The car of a weak pair holds its pointer weakly, while the cdr holds its pointer strongly. If the object in the car of a weak pair is not held strongly by any other data structure, it will be garbage-collected.

Note: weak pairs can be defeated by cross references among their slots. Consider a weak pair P holding an object A in its car and an object D in its cdr. P points to A weakly and to D strongly. If D holds A strongly, however, then P ends up holding A strongly after all. If avoiding this is worth a heavier-weight structure, See Ephemerons.

Note: weak pairs are not pairs; that is, they do not satisfy the predicate `pair?`.

— procedure: weak-pair? object

Returns `#t` if object is a weak pair; otherwise returns `#f`.

— procedure: weak-cons car cdr

Allocates and returns a new weak pair, with components car and cdr. The car component is held weakly.

— procedure: weak-pair/car? weak-pair

This predicate returns `#f` if the car of weak-pair has been garbage-collected; otherwise returns `#t`. In other words, it is true if weak-pair has a valid car component.

— procedure: weak-car weak-pair

Returns the car component of weak-pair. If the car component has been garbage-collected, this operation returns `#f`, but it can also return `#f` if that is the value that was stored in the car.

Normally, `weak-pair/car?` is used to determine if `weak-car` would return a valid value. An obvious way of doing this would be:

```     (if (weak-pair/car? x)
(weak-car x)
...)
```

However, since a garbage collection could occur between the call to `weak-pair/car?` and `weak-car`, this would not always work correctly. Instead, the following should be used, which always works:

```     (or (weak-car x)
(and (not (weak-pair/car? x))
...))
```

The reason that the latter expression works is that `weak-car` returns `#f` in just two instances: when the car component is `#f`, and when the car component has been garbage-collected. In the former case, if a garbage collection happens between the two calls, it won't matter, because `#f` will never be garbage-collected. And in the latter case, it also won't matter, because the car component no longer exists and cannot be affected by the garbage collector.

— procedure: weak-set-car! weak-pair object

Sets the car component of weak-pair to object and returns an unspecified result.

— procedure: weak-cdr weak-pair

Returns the cdr component of weak-pair.

— procedure: weak-set-cdr! weak-pair object

Sets the cdr component of weak-pair to object and returns an unspecified result.