### 10.8 Ephemerons

An ephemeron is an object with two weakly referenced components called its key and datum. The garbage collector drops an ephemeron’s references to both key and datum, rendering the ephemeron broken, if and only if the garbage collector can prove that there are no strong references to the key. In other words, an ephemeron is broken when nobody else cares about its key. Note that an ephemeron’s reference to its datum may be dropped even if the datum is still reachable; all that matters is whether the key is reachable. Once broken, ephemerons never cease to be broken; setting the key or datum of a broken ephemeron with `set-ephemeron-key!` or `set-ephemeron-datum!` has no effect.

Ephemerons are considerably heavier-weight than weak pairs, because garbage-collecting ephemerons is more complicated than garbage-collecting weak pairs. Each ephemeron needs five words of storage, rather than the two words needed by a weak pair. However, while the garbage collector spends more time on ephemerons than on other objects, the amount of time it spends on ephemerons scales linearly with the number of live ephemerons, which is how its running time scales with the total number of live objects anyway.

procedure: ephemeron? object

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

procedure: make-ephemeron key datum

  Allocates and returns a new ephemeron, with components key and datum.

procedure: ephemeron-broken? ephemeron

  Returns `#t` if the garbage collector has dropped ephemeron’s references to its key and datum; otherwise returns `#f`.

procedure: ephemeron-key ephemeron
procedure: ephemeron-datum ephemeron

  These return the key or datum component, respectively, of ephemeron. If ephemeron has been broken, these operations return `#f`, but they can also return `#f` if that is the value that was stored in the key or value component.

procedure: set-ephemeron-key! ephemeron object
procedure: set-ephemeron-datum! ephemeron object

  These set the key or datum component, respectively, of ephemeron to object and return an unspecified result. If ephemeron is broken, neither of these operations has any effect.

Like `weak-pair/car?`, `ephemeron-broken?` must be used with care. `Ephemeron-broken?` on an ephemeron guarantees that any prior call to `ephemeron-key` or `ephemeron-datum` on the same ephemeron yielded the key or datum that was stored in the ephemeron, but it makes no guarantees about subsequent calls to `ephemeron-key` or `ephemeron-datum`. Thus, the correct idiom to fetch an ephemeron’s key and datum and use them if the ephemeron is not broken is

    (let ((key (ephemeron-key ephemeron))
          (datum (ephemeron-datum ephemeron)))
      (if (ephemeron-broken? ephemeron)
          … broken case …
          … code using key and datum …))