I think the high-level answer is that you have to understand something about details that aren't currently specified but nevertheless are how things currently work and then make a test that will work when you make those additional assumptions (and then keep it running in drdr so you can tell when the assumptions get broken).
In this case, I think that a weak box is going to work well to test the code you described at the beginning of this thread. That is, create the array; use some internal thing to extract the procedure from it. Put it into a weak-box; change the state; collect garbage, check the box. I think that won't fail unless you let that procedure be reachable from a finalizer or you somehow get it promoted to the master area (between places) .. or there is a bug. :) Robby On Sat, Dec 1, 2012 at 8:05 PM, Neil Toronto <neil.toro...@gmail.com> wrote: > Ah. It prints #f for me when I have debugging info turned on in DrRacket; > otherwise I get #<procedure>. Must be inlining keeping it around or > something. > > The problem with either finalizers or weak boxes is that neither provides > enough guarantees. Finalizers are never guaranteed to be run. A weak box may > not be the only reference to a procedure value, depending on what > optimizations are done. I'm trying to test something that's normally not > supposed to be observable. > > For now, I've got a finalizer on an array procedure that's created at the > beginning of the 1000-line test module, and I test that the finalizer was > run at the end. I've also got a (collect-garbage) and a (sleep 0) in there. > It works... for now, on my machine. > > Maybe a weak box containing a random closure would work. Hmm... > > > On 12/01/2012 06:46 PM, Robby Findler wrote: >> >> This prints #f for me. >> >> #lang racket >> >> (define (make-box-thing v) >> (make-weak-box (λ (_) v))) >> >> (define bx (make-box-thing 4)) >> (collect-garbage) >> (weak-box-value bx) >> >> And I guess that non-closure procedures are held onto by the modules >> they are inside. This program prints #f for me, and it seems to >> confirm that hypothesis. >> >> #lang racket >> >> (define bx >> (parameterize ([current-namespace (make-base-namespace)]) >> (eval '(module m racket >> (define bx (make-weak-box (λ (_) 1))) >> (provide bx))) >> (eval '(require 'm)) >> (eval 'bx))) >> >> (collect-garbage) >> (weak-box-value bx) >> >> Robby >> >> On Sat, Dec 1, 2012 at 7:30 PM, Neil Toronto <neil.toro...@gmail.com> >> wrote: >>> >>> Honestly, because I was too rushed to try them before I had to leave this >>> morning. :D However, now that I have the chance, I've found that Typed >>> Racket doesn't support them. I can't add support using `required/typed', >>> because `Weak-Box' would have to be a polymorphic type. >>> >>> Also, they don't seem to let go of procedure values. This one's value >>> doesn't ever turn to #f no matter how many times I collect garbage: >>> >>> (define bx (make-weak-box (λ (_) 0))) >>> >>> Thinking it might be because that lambda doesn't create a closure, I >>> tried >>> this: >>> >>> (define (make-box-thing v) >>> (make-weak-box (λ (_) v))) >>> >>> (define bx (make-box-thing 4)) >>> >>> But this `bx' doesn't let go of its value, either. I can't help but think >>> I'm missing something really stupid, though. >>> >>> Neil ⊥ >>> >>> >>> On 12/01/2012 10:58 AM, Robby Findler wrote: >>>> >>>> >>>> How about using a weak box instead? >>>> >>>> Robby >>>> >>>> On Sat, Dec 1, 2012 at 11:45 AM, Neil Toronto <neil.toro...@gmail.com> >>>> wrote: >>>>> >>>>> >>>>> I'm getting ready to push a change to math/array that fixes a memory >>>>> leak. >>>>> I've devised a test that I think will determine whether an array's >>>>> procedure >>>>> gets collected after the array is made strict, but I don't know whether >>>>> it >>>>> works only by accident. Here it is: >>>>> >>>>> >>>>> (define: collected? : (Boxof Boolean) (box #f)) >>>>> >>>>> (define arr >>>>> (let ([proc (λ: ([js : Indexes]) 0)]) ; constant array >>>>> (register-finalizer proc (λ (proc) (set-box! collected? #t))) >>>>> (build-array #() proc))) >>>>> >>>>> (array-strict! arr) >>>>> (collect-garbage) >>>>> (sleep 0) ; give finalizers a chance to run? >>>>> (check-true (unbox collected?)) >>>>> >>>>> >>>>> This test passes for me now, but will fail if anyone else tries it. >>>>> What >>>>> worries me is that (sleep 0) is apparently required, meaning that >>>>> finalizers >>>>> aren't run immediately when garbage is collected. >>>>> >>>>> How can I ensure that the finalizer for `proc' gets run before I test >>>>> the >>>>> value of `collected?'? >>>>> >>>>> Neil ⊥ >>>>> _________________________ >>>>> Racket Developers list: >>>>> http://lists.racket-lang.org/dev >>> >>> >>> > _________________________ Racket Developers list: http://lists.racket-lang.org/dev