[racket] Help: Passing a class to a macro and not an identifier

From: Robby Findler (robby at eecs.northwestern.edu)
Date: Wed Sep 15 09:46:12 EDT 2010

On Wed, Sep 15, 2010 at 8:31 AM, Laurent <laurent.orseau at gmail.com> wrote:
>
>
> On Wed, Sep 15, 2010 at 15:19, Robby Findler <robby at eecs.northwestern.edu>
> wrote:
>>
>> The class exists at runtime, not at compile time, so you can't just
>> take an identifier like that and get the names of the methods back.
>> (This is a fundamental difference between our class system and ones
>> like in Java. See
>> http://www.eecs.northwestern.edu/~robby/pubs/papers/aplas2006-fff.pdf
>> for more info about the high level properties of the class system.)
>>
>> At least not with the current class system. You can, however, define a
>> macro, something like:
>>
>> (define-class <name> <class-expr>)
>>
>> and then have define-class inspect the class-expr to find the method
>> names (note you'll have to use local-expand to make this work) and put
>> that information into <name> at compile time.
>
> Or maybe I can define a% in a separate module and require it for-syntax
> either?

Only if you restrict the way classes are written.

> So here is where I am right now:
>
> #lang racket
>
> (require
>   "a.rkt"
>   (for-syntax "a.rkt"))
>
> (define-syntax-rule (define-singleton-sender fun obj meth)
>   (define-syntax-rule (fun args (... ...))
>     (send (obj) meth args (... ...))))
>
> (define-syntax (class->singleton stx)
>   (syntax-case stx ()
>     [(_ cl obj)
>      (with-syntax ([(name ...)
>                     (interface->method-names (class->interface a%))]) ; ***
>        #'(begin (define-singleton-sender name obj name)
>                 ...))]))
>
> (define current-a (make-parameter (new a% [a 3])))
>
> (class->singleton a% current-a)
>
> This works for class a%, but only for this one, as I don't know how to pass
> a%
> as an argument to the macro (note the a% on line ***).
> How can I do that?

This is a kind of strange way to go about this problem. I'm not sure
if it can be made to work or if there are strange problems lurking
down the road. Probably there is a way to do this, but I don't see it,
possibly being blinded by how strange this seems to be.

I guess you could trying using dynamic-require. Of course lots of
things break then.

Robby


Posted on the users mailing list.