# (lispkit box)

LispKit is a R7RS-compliant implementation with one exception: pairs are immutable. This library provides implementations of basic mutable data structures with reference semantics: mutable multi-place buffers, also called *boxes*, mutable pairs, and *atomic boxes*. The difference between a two-place box and a mutable pair is that a mutable pair allows mutations of the two elements independent of each other. The difference between a *box* and an *atomic box* is that access to atomic boxes is synchronized such that reading and writing is atomic.

## Boxes

**(box?&#x20;*****obj*****)**     <img src="/files/STqjiJsrexexyFklGQwH" alt="" data-size="line">

Returns `#t` if *obj* is a box; `#f` otherwise.

**(box&#x20;*****obj ...*****)**     <img src="/files/STqjiJsrexexyFklGQwH" alt="" data-size="line">

Returns a new box object that contains the objects *obj ...*.

**(unbox&#x20;*****box*****)**     <img src="/files/STqjiJsrexexyFklGQwH" alt="" data-size="line">

Returns the current contents of *box*. If multiple values have been stored in the box, `unbox` will return multiple values. This procedure fails if *box* is not referring to a box.

**(set-box!&#x20;*****box obj ...*****)**     <img src="/files/STqjiJsrexexyFklGQwH" alt="" data-size="line">

Sets the content of *box* to objects *obj ...*. This procedure fails if *box* is not referring to a box.

**(update-box!&#x20;*****box proc*****)**     <img src="/files/STqjiJsrexexyFklGQwH" alt="" data-size="line">

Invokes *proc* with the content of *box* and stores the result of this function invocation in *box*. `update-box!` is implemented like this:

```scheme
(define (update-box! box proc)
  (set-box! box (apply-with-values proc (unbox box))))
```

## Mutable pairs

**(mpair?&#x20;*****obj*****)**     <img src="/files/STqjiJsrexexyFklGQwH" alt="" data-size="line">

Returns `#t` if v is a mutable pair (mpair); `#f` otherwise.

**(mcons&#x20;*****car cdr*****)**     <img src="/files/STqjiJsrexexyFklGQwH" alt="" data-size="line">

Returns a new mutable pair whose first element is set to *car* and whose second element is set to *cdr*.

**(mcar&#x20;*****mpair*****)**     <img src="/files/STqjiJsrexexyFklGQwH" alt="" data-size="line">

Returns the first element of the mutable pair *mpair*.

**(mcdr&#x20;*****mpair*****)**     <img src="/files/STqjiJsrexexyFklGQwH" alt="" data-size="line">

Returns the second element of the mutable pair *mpair*.

**(set-mcar!&#x20;*****mpair obj*****)**     <img src="/files/STqjiJsrexexyFklGQwH" alt="" data-size="line">

Sets the first element of the mutable pair *mpair* to *obj*.

**(set-mcdr!&#x20;*****mpair obj*****)**     <img src="/files/STqjiJsrexexyFklGQwH" alt="" data-size="line">

Sets the second element of the mutable pair *mpair* to *obj*.

## Atomic boxes

**atomic-box-type-tag**   <img src="/files/viHiVHsCY8Wn2TeCgWJj" alt="" data-size="line">

Symbol representing the `atomic-box` type. The `type-for` procedure of library `(lispkit type)` returns this symbol for all atomic box objects.

**(atomic-box?&#x20;*****obj*****)**     <img src="/files/STqjiJsrexexyFklGQwH" alt="" data-size="line">

Returns `#t` if *obj* is an atomic box; `#f` otherwise.

**(make-atomic-box&#x20;*****obj ...*****)**     <img src="/files/STqjiJsrexexyFklGQwH" alt="" data-size="line">

Returns a new atomic box that contains the objects *obj ...*.

**(atomic-box-ref&#x20;*****abox*****)**     <img src="/files/STqjiJsrexexyFklGQwH" alt="" data-size="line">

Returns the current contents of atomic box *abox* synchronizing access such that it is atomic. If multiple values have been stored in *abox*, `atomic-box-ref` will return multiple values. This procedure fails if *abox* is not referring to an atomic box.

**(atomic-box-set!&#x20;*****abox obj ...*****)**     <img src="/files/STqjiJsrexexyFklGQwH" alt="" data-size="line">

Sets the content of *abox* to objects *obj ...* synchronizing access such that it is atomic. This procedure fails if *abox* is not referring to an atomic box.

**(atomic-box-swap!&#x20;*****abox obj ...*****)**     <img src="/files/STqjiJsrexexyFklGQwH" alt="" data-size="line">

Sets the content of *abox* to objects *obj ...* synchronizing access such that it is atomic. This procedure fails if *abox* is not referring to an atomic box. This procedure returns the former values of *abox*.

**(atomic-box-compare-and-set!&#x20;*****abox curr obj ...*****)**     <img src="/files/STqjiJsrexexyFklGQwH" alt="" data-size="line">

Sets the content of *abox* to objects *obj ...* if the values of *abox* match *curr*; in this case `#t` is returned. If the values of *abox* do not match *curr*, the values of *abox* remain untouched and `#f` is returned. This operation is atomic and fails if *abox* is not referring to an atomic box.

**(atomic-box-compare-and-swap!&#x20;*****abox curr obj ...*****)**     <img src="/files/STqjiJsrexexyFklGQwH" alt="" data-size="line">

Sets the content of *abox* to objects *obj ...* if the values of *abox* match *curr*. If the values of *abox* do not match *curr*, the values of *abox* remain untouched. This operation is atomic and fails if *abox* is not referring to an atomic box. It returns the former values of *abox*.

**(atomic-box-inc+mul!&#x20;*****abox i1*****)**     <img src="/files/STqjiJsrexexyFklGQwH" alt="" data-size="line">\
\&#xNAN;**(atomic-box-inc+mul!&#x20;*****abox i1 m*****)**\
\&#xNAN;**(atomic-box-inc+mul!&#x20;*****abox i1 m i2*****)**

This procedure can be used for atomic boxes containing a single value of type *flonum* or *fixnum* to update its value *x* with *(x + i1) \* m + i2* in a synchronized fashion. `atomic-box-inc+mul!` returns the new value of *abox*.

**(atomic-box-update!&#x20;*****abox proc*****)**     <img src="/files/STqjiJsrexexyFklGQwH" alt="" data-size="line">

Invokes *proc* with the content of *abox* and stores the result of this function invocation in *abox*. The computation of the new value and the update of *abox* is performed atomically and the new value of *abox* is returned by `atomic-box-update!`.


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://www.lisppad.app/libraries/lispkit/lispkit-box.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
