Weak Pairs - MIT/GNU Scheme 9.1
Description: MIT/GNU Scheme 9.1

Next: Ephemerons, Previous: Streams, Up: Miscellaneous Datatypes

### 10.7 Weak Pairs

Weak pairs are a mechanism for building data structures that point at objects without protecting them from garbage collection. The car of a weak pair holds its pointer weakly, while the cdr holds its pointer in the normal way. If the object in the car of a weak pair is not held normally by any other data structure, it will be garbage-collected.

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-cdr.

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

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