At Thu, 16 Nov 2017 18:40:14 -0500, David Storrs wrote:
> From the Guide:
> -------
> This code [...] has a subtle bug:
> #lang racket
> (let* ([fishes (list (fish 8 'red)
>                      (fish 7 'blue))]
>        [wb (make-weak-box (list-ref fishes 0))])
>   (collect-garbage)
>   (printf "still there? ~s\n" (weak-box-value wb)))
> Specifically, it will show that the weak box is empty, but not because
> fishes no longer holds onto the value, but because fishes itself is
> not reachable anymore!
> -------
> The reason it's not reachable is because it is not actually referred
> to in the source code, right?  It is theoretically still reachable in
> the scope of the 'collect-garbage' call **if you actually put a
> mention of it in the code** but in this particular case it's not
> reachable because there is no such reference.
> In the next section they do exactly that and state that fishes is now
> reachable again, so I want to confirm that I understand properly what
> caused the change.

Yes, that's basically correct.

Beware that the requirement is a little stronger than "actually put a
mention of it in the code". The mention has to be itself something that
will execute, or that the compiler cannot prove won't execute.

For example, the output will show "#f" for

 (let* ([fishes (list (fish 8 'red)
                      (fish 7 'blue))]
        [wb (make-weak-box (list-ref fishes 0))])
   (printf "still there? ~s\n" (weak-box-value wb))
   (if #f

because the compiler can trivially discard the first branch of the

The compiler is also able to discard the first branch in

  (if (not (pair? fishes))

since it can track that `fishes` is a non-empty list. On the other
hand, the compiler is not currently able to discard the first branch in

  (if (= 0 (length fishes))

since it doesn't track enough to know that `(length fishes)` will
always produce 2 and never 0.

Having to predict the compiler's behavior is problem; a some level,
weak references are just not usable that way. For cases where it makes
sense to drop down to implementation dependencies, the `ffi/unsafe`
library provides `void/reference-sink` to help create a reference that
the compiler cannot optimize away.

You received this message because you are subscribed to the Google Groups 
"Racket Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
For more options, visit

Reply via email to