You may be surprised to learn that set!
is implemented using boxes. That is, code such as:
(let ([a 1])
(set! a 2)
(+ a 1))
Is translated into:
(let ([a (box 1)])
(set-box! a 2)
(+ (unbox a) 1))
You will often hear that mutable code is slower in Racket, and this is the reason why: every time you use set!
the compiler has to box the variable and unbox it everywhere it is used -- this severely reduces the opportunities for optimizations.
As for box-cas!
, a lot of synchronization mechanisms can be implemented using a compare-and-swap operation -- most processors provide a single machine instruction for this.
Boxes are another "under-the-hood" feature, less useful to the application programmer, but useful to language developers.
For a related discution, see What are examples of use-cases for continuations?
Alex.