[plt-scheme] PLT Object System

From: Matthias Felleisen (matthias at ccs.neu.edu)
Date: Sun Feb 20 12:35:42 EST 2005

On Feb 20, 2005, at 11:19 AM, David J. Neu wrote:
> The example below works up until the last line:
> (require (lib "class.ss"))
>  (define foo%
>    (class object%
>      (init-field x
>                  (get (lambda () x))
>                  (set (lambda (_x) (set! x _x))))
>      (set x)
>      (super-new)))
> (define bar (new foo% (x 2)))
> (display (get-field x bar)) (newline)
> (define barbar (new foo% (x 2) (get (lambda () (add1 x)))))
> (display (send get x barbar)) (newline) ;; FAILS - no GET method

It depends on what you mean by work.

(define bar (new foo% (x 2)))
(display (get-field x bar)) (newline)

;; I have added a line here:

(display [(get-field get bar)]) (newline)

;; This will work in the sense that you mean "work." "-)

(define barbar (new foo% (x 2) (get (lambda () (add1 x)))))

What you failed to report is that drscheme reports x is unbound in the 
above closure, and that is the crux of the problem.  As you know, the 
evaluation of (lambda ...) creates a closure in the _current_ 
environment. So before you evaluate the new expression, the expressions 
for its fields are evaluated. Boom things break.

(display [(get-field get barbar)]) (newline) ;; FAILS - no GET method

Finally I have corrected your syntax for extracting the get field from 
barbar. The brackets are the invocations of the thunk you get back.

Richard has suggested an alternative solution, so I will leave it at 
that -- Matthias

Posted on the users mailing list.