[racket] Web-cells, anonymous functions, and garbage collection

From: Jay McCarthy (jay.mccarthy at gmail.com)
Date: Thu Feb 14 08:45:56 EST 2013

When I say "code", I mean module top-level binding byte-code. There's
no way for Racket to remove

(define (f x) (lambda (y) (printf "Gigantic string: ~a" (+ x y))))

at the top-level. The byte-code will always contain the gigantic
string. If you ever call f and get back something, that closure could
be collected, but not the source that generated it.

Jay

On Thu, Feb 14, 2013 at 6:37 AM, Robby Findler
<robby at eecs.northwestern.edu> wrote:
> I'm pretty sure code is collected in (regular) Racket. Small numbers aren't
> collected, true, but they also don't really take any space. Big numbers are
> collected, too. (I'm not sure about interned symbols.)
>
> Robby
>
>
> On Thu, Feb 14, 2013 at 7:26 AM, Jay McCarthy <jay.mccarthy at gmail.com>
> wrote:
>>
>> In the Web server language, all anonymous functions are turned into
>> top-level structures masquerading as functions where the fields are
>> their free variables. For instance:
>>
>> (define (f x) (lambda (y) (+ x y))
>>
>> becomes, roughly,
>>
>> (struct a-lambda42 (x)
>>  #:property prop:procedure
>>  (lambda (the-structure y)
>>   (define x (a-lambda42-x the-structure))
>>   (+ x y)))
>> (define (f x) (make-a-lambda42 x))
>>
>> In your program, the expression
>>
>> (web-cell-shadow wc-anonymous (λ (x) 'more-distinctive-text))
>>
>> becomes
>>
>> (struct a-lambda43 () #:property prop:procedure (lambda (s x)
>> 'more-distinctive-text))
>> (web-cell-shadow wc-anonymous (make-a-lambda43))
>>
>> Notice that the anonymous function has no fields because there are no
>> free variables. The distinctive text is not shown anywhere in the URL
>> because it is part of the code, not part of the data, of the closure.
>>
>> If you change the program slightly to
>>
>> (web-cell-shadow wc-anonymous
>>                  (let () (define y 'more-distinctive-text)
>>                       (λ (x) y)))
>>
>> then y is a free variable, so when you look at the URL:
>>
>>
>> http://localhost:8000/;((%22c%22%20.%20%220((3)%204%20(((lib%20%5C%22web-server%2Flang%2Fabort-resume.rkt%5C%22)%20.%20%5C%22lifted.6%5C%22)%20((lib%20%5C%22web-server%2Flang%2Fweb-cells.rkt%5C%22)%20.%20deserialize-info:frame-v0)%20(%23%5C%22%2Ftmp%2Ft.rkt%5C%22%20.%20%5C%22lifted.1683%5C%22)%20(2%20.%20%5C%22lifted.1991%5C%22))%200%20()%20()%20(0%20(1%20(h%20-%20()%20(lifted.1485-0%20.%20this-is-a-song-about-Japan)%20(lifted.1521-1%202%20(b!%20.%20more-distinctive-text))))%20(c%20(v!%20(3)%20%23f%20%23f))))%22))
>>
>> You see the distinctive text.
>>
>> As far as GC goes, code is not generally collected in Racket anyways.
>> Any data that is an intrinsic part of the program text (such as
>> literal symbols and numbers) will always be around in your program
>> whether you use #lang web-server or not.
>>
>> Jay
>>
>>
>> On Wed, Feb 13, 2013 at 8:34 PM, Galler <lzgaller at optonline.net> wrote:
>> > Good evening,
>> >
>> > I've been investigating lang web-server, performance and garbage
>> > collection
>> >
>> > I have a question regarding anonymous functions and web cells
>> >
>> > Examples below require:
>> >
>> > #lang web-server
>> > (require racket/serialize
>> >          web-server/lang/web-cells)
>> >
>> >
>> > Constants appear serializable by their value being explicitly written
>> > out
>> >
>> >
>> > For example,
>> >
>> > (serialize 'this-is-a-song-about-japan)
>> >
>> > ;-> '((3) 0 () 0 () () this-is-a-song-about-japan)
>> >
>> >
>> > Whereas anonymous functions appear serializable by the mechanism of
>> > being
>> > "lifted" (i.e. reified) to a module level binding
>> >
>> > For example
>> >
>> > (serialize (λ (x) x))
>> >
>> > ;-> '((3) 1 (('anonymous-module . "lifted.1386")) 0 () () (0))
>> >
>> >
>> > Moving the discussion to web-cells
>> >
>> > (define wc-constant (make-web-cell #f))
>> >
>> > (define wc-anonymous (make-web-cell #f))
>> >
>> >
>> > (web-cell-shadow wc-constant 'this-is-a-song-about-Japan)
>> >
>> > (web-cell-shadow wc-anonymous (λ (x) x))
>> >
>> >  (printf " wc-constant: ~A\n wc-anonymous: ~A\n"
>> >           (serialize wc-1)
>> >           (serialize wc-2))
>> >
>> > returns
>> >
>> > wc-constant: ((3) 1 (((lib web-server/lang/web-cells.rkt) .
>> > deserialize-info:primitive-wc-v0)) 0 () () (0 lifted.1534-0))
>> >
>> > wc-anonymous: ((3) 1 (((lib web-server/lang/web-cells.rkt) .
>> > deserialize-info:primitive-wc-v0)) 0 () () (0 lifted.1570-1))
>> >
>> >
>> >
>> > While now both values are 'lifted' (i.e. reified), a close examination
>> > of
>> > the URL-string sent back to a client after send/suspend/dispatch
>> >
>> > reveals that, with respect to the constant, lifted.1534 appears to be
>> > explicitly represented, elsewhere in the string as an associative pair
>> > i.e.
>> > (lifted.1534 this-is-a-song-about-Japan)
>> >
>> > whereas for the anonymous function, its not clear that its reference,
>> > lifted.1570 is explicitly represented
>> >
>> > Which leads me to wonder about whether the reference to the anonymous
>> > function, lifted.1570, is being maintained on the server,
>> >
>> > And if so, how is it being garbage collected, as its impossible to ever
>> > determine that it is unreachable.
>> >
>> > I will also point out that prior to a year ago, anonymous functions
>> > failed
>> > the serializability predicate. (serializable? anon-func) -> #f. I can
>> > pull
>> > out the correspondence/background related to that if desirable.
>> >
>> > I apologize if I'm just misreading the data.
>> >
>> > Here's the complete example,with a stateless web server. Note that when
>> > you
>> > inspect the url-string**for the datum this-is-a-song-about-Japan, its
>> > there,
>> > but when looking for the datum more-distinctive-text, its not present in
>> > the
>> > url-string.
>> >
>> > **right click on the link, then copy/paste, or click the 'click-me' link
>> > and
>> > copy/paste the URL from the address bar)
>> >
>> > Thanks very much.
>> >
>> >
>> > Thanks again.
>> >
>> >
>> >
>> > #lang web-server
>> >
>> > (require  web-server/servlet-env)
>> >
>> > (define wc-constant (make-web-cell #f))
>> >
>> > (define wc-anonymous (make-web-cell #f))
>> >
>> >
>> > (web-cell-shadow wc-constant 'this-is-a-song-about-Japan)
>> >
>> > (web-cell-shadow wc-anonymous (λ (x) 'more-distinctive-text))
>> >
>> > (define (start request)
>> >   (letrec ((response-generator (λ (make-url)
>> >                               (response/xexpr `(html (head)
>> >                                                      (body (a ((href
>> > ,(format "~A" (make-url receive-request)))) "click me"))))))
>> >            (receive-request (λ (request)
>> >                               (response/xexpr `(html (head)
>> >                                                      (body "Thank you.
>> > We
>> > are done."))))))
>> >     (send/suspend/dispatch response-generator)))
>> >
>> > (serve/servlet start
>> >                #:stateless? #t
>> >                #:launch-browser? #t
>> >                #:connection-close? #t
>> >                #:quit? #f
>> >                #:listen-ip #f
>> >                #:port 8000
>> >                #:servlet-path "/")
>> >
>> >
>> >
>> > Thanks much.
>> >
>> > Zack
>>
>>
>>
>> --
>> Jay McCarthy <jay at cs.byu.edu>
>> Assistant Professor / Brigham Young University
>> http://faculty.cs.byu.edu/~jay
>>
>> "The glory of God is Intelligence" - D&C 93
>>
>> ____________________
>>   Racket Users list:
>>   http://lists.racket-lang.org/users
>
>



--
Jay McCarthy <jay at cs.byu.edu>
Assistant Professor / Brigham Young University
http://faculty.cs.byu.edu/~jay

"The glory of God is Intelligence" - D&C 93


Posted on the users mailing list.