[plt-scheme] how to abstract over (new ...) expressions?

From: Richard Cobbe (cobbe at ccs.neu.edu)
Date: Fri May 5 12:04:02 EDT 2006

How does one abstract over (new ...) expressions?

Here's the situation:

(define-struct base (x))
(define-struct (A base) ())
(define-struct (B base) (y))

(define A%
  (class object%
    [init-field fd1]
    ...))

(define B%
  (class object%
    [init-field fd1]
    [init-field fd2]
    ...))

I need to convert instances of A and B into instances of A% and B%
respectively:

(define (convert st)
  (if (A? st)
    (new A% [fd1 (f (base-x st))])
    (new B% [fd1 (f (base-x st))]
            [fd2 (g (B-y st))])))

where f and g are some translation functions whose details aren't
relevant.

There's some common code here that I'd like to abstract out (especially
because in my real application, the classes share 5 fields and the
associated 5 translation functions; the second class only adds a single
field).  But I can't find an elegant way to do this.

Doing this with a straightforward function won't work, since there's
some syntax involved in the name-expression pairs.

Doing this with a macro doesn't seem to work, because I have to make
expansion-time decisions based on run-time values -- I have to expand in
a slightly different way depending on whether the value of the argument
is an A or a B.

The best I can come up with is playing nasty games with apply,
make-object, and list manipulation, but I don't like that very much (not
least because I don't want to rely on the order of these arguments in
the class definitions).

Are there any possibilities I'm overlooking?

Richard


Posted on the users mailing list.