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

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

I must admit, what you've done is quite the clever hack. You're
loading the same file both at compile and and at runtime. At compile
time you look at the exports using the (normally) runtime inspection
facilities of the class system and use that to guide how compilation
then happens of the module that interacts with the same file at
runtime.

This hack will have limitations, but you could take this one step
further by having the argument to your macro be an identifier and then
taking the symbolic name of the identifier and passing that to
dynamic-require (at compile time) to get the actual class you want.

If you can change the file that defines a%, you can make it export a
kind of "table of contents" and then iterate over that too.

Robby

2010/9/15 Laurent <laurent.orseau at gmail.com>:
>
>
> On Wed, Sep 15, 2010 at 16:17, Matthias Felleisen <matthias at ccs.neu.edu>
> wrote:
>>
>> Now see Robby's answer.
>
> I have, several times, but I must be blind.
> The code I gave works for class a%, so certainly a% can be "inspected" by
> (interface->method-names (class->interface a%))
> during the expansion of the macro, and it generates the functions names
> according to the method names, so that their existence is detected at
> compile
> time (thanks to datum->syntax).
> I suspect this is why the last line '(get-the-val)' in the module doesn't
> raise
> a syntax error.
>
> The only remaining problem I have is to abstract class->singleton over a%,
> so that the class can be given as an argument to the macro.
>
> Ah, in fact I've just found a (probably ugly) workaround that I hope to
> improve
> (see below):
> To abstract over a%, I just turned class->singleton into a macro-maker
> that takes a class (at compile time) and instantiate define-class->singleton
> for a given class.
>
> I am a bit puzzled since this does not match your (kind) answers so I must
> have either badly explained my problem, or badly understood your answers
> (or both).
>
> Anyway, thanks a lot for your help.
>
> Laurent
> P.S.: If anyone knows how to improve this, I'm interested.
>
>
>
> <singleton.rkt>
> #lang racket
>
> (require (for-syntax racket/class))
>
> (define-syntax-rule (define-singleton-sender func obj meth)
>   (begin (printf "define-sender: ~s ~s ~s\n" 'func 'obj 'meth)
>          (define (func . args)
>            (send/apply (obj) meth args))))
>
> (define-syntax-rule (define-class->singleton define-name cl)
>   (define-syntax (define-name stx)
>     (syntax-case stx ()
>       [(_ obj)
>        (with-syntax ([(name (... ...))
>                       (map (λ(n)(datum->syntax #'obj n))
>                            (interface->method-names (class->interface
> cl)))])
>          #'(begin (define-singleton-sender name obj name)
>                   (... ...)))])))
>
> ; Tests
>
> (require "a.rkt"
>          (for-syntax "a.rkt"))
>
> ; Instantiate the macro for a% :
> (define-class->singleton a%->singleton a%)
>
> (define current-a (make-parameter (new a% [val 3])))
>
> (a%->singleton current-a)
>
> (get-the-val)
>
> ->
> define-sender: get-the-val current-a get-the-val
> 3
>
>
>
> _________________________________________________
>  For list-related administrative tasks:
>  http://lists.racket-lang.org/listinfo/users
>


Posted on the users mailing list.