[racket] Box: When and why?

From: Matthias Felleisen (matthias at ccs.neu.edu)
Date: Thu Oct 21 11:41:30 EDT 2010

Boxes are the closest thing to addresses you can find in Racket. 
You need them when you want to mimic a classical by-reference 
function parameter protocol. For example, 

 (define (return-nothing x y z a-box)
   (set-box! a-box ComputeSomethingWith-x-y-z)
   (void) ;; just to make clear that nothing else is returned 
   ) 

You'd call this elsewhere with 

 (define my-personal-box (box #f))
 ...
 (return-nothing my-personal-box)
 (unbox my-personal-box)

You can imagine that you have some other ways of referring to 
my-personal-box (say in a list of all your boxes) which you may
then use to implement other services (saving all boxes to a file). 

Some of our old methods that go down to C++ use this protocol. 

In your 'p.s.' example, there is no reason whatsoever to 
use a box over set! and variables. 

-- Matthias


 


On Oct 21, 2010, at 11:31 AM, Greg Hendershott wrote:

> P.S. Maybe a simpler example I should have used:
> 
> (define next-web-parameter-id
>  (let ([i (box 0)])
>    (lambda ()
>      (begin0 (unbox i)
>              (set-box! i (add1 (unbox i)))))))
> 
> In both examples the box is involved in a closure lambda pattern.
> 
> This example, my old C/C++ brain wants to interpret it as a kind of
> thread-safe increment of a variable. But what's really going on?
> 
> On Thu, Oct 21, 2010 at 11:22 AM, Greg Hendershott
> <greghendershott at gmail.com> wrote:
>> Where can I find more information about the use scenarios for "box"?
>> 
>> The Guide is terse:
>> 
>>>> 
>> 3.11 Boxes
>> 
>> A box is like a single-element vector. It can print as a quoted #&
>> followed by the printed form of the boxed value. A #& form can also be
>> used as an expression, but since the resulting box is constant, it has
>> practically no use.
>> <<
>> 
>> This explains what a box is, but not why or when you would want to use one.
>> 
>> I see box used as in this example from servlet-dispatch.rkt:
>> 
>> (define (dispatch/servlet
>> ...
>>  (define servlet-box (box #f))
>> ...
>>  (filter:make
>> ...
>>    (lambda (url)
>>      (or (unbox servlet-box)
>>          (let ([servlet
>>                 (parameterize ([current-custodian (make-custodian)]
>>                                [current-namespace
>>                                 (make-servlet-namespace
>>                                  #:additional-specs
>>                                  default-module-specs)])
>>                   (if stateless?
>>                       (make-stateless.servlet
>> servlet-current-directory stuffer manager start)
>>                       (make-v2.servlet servlet-current-directory
>> manager start)))])
>>            (set-box! servlet-box servlet)
>>            servlet))))))
>> 
>> And I'm scratching my head, not understanding the point of using a box
>> as opposed to a simple non-boxed value.
>> 
>> My question isn't about this code per se; only an example. Generally,
>> in what situations would you use a box, and why?
>> 
>> Thank you.
>> 
> _________________________________________________
>  For list-related administrative tasks:
>  http://lists.racket-lang.org/listinfo/users



Posted on the users mailing list.