-----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 On 13-01-12 08:20, Hal Henke wrote: > Hi Marjin, > > Firstly - wow sorry about all that html :-(
No problem. > Secondly thanks very much for your help - your example worked > great. Only thing is - I'm having trouble generalising the macro to > handle multiple arguments. The real problem seems to be that > anytime the term init, init-field, define/public is mentioned > inside a class, inside a list or any other type of s-expression an > error gets thrown > > "init-field: use of a class keyword is not in a class top-level > in: (init-field _field_)" It's complaining about your using `init-field' outside of `class'. > so 'm having real difficulty trying to get a macro that spits out > an arbitrary number of init field define-public pairs e.g. > > (class object% (super-new) (init-field a1) (define/public (get-a1) > a1) (init-field a2) (define/public (get-a1) a2) etc... ) > > So far ive been mucking round with something like this to no > success: Your mucking is very familiar and reminds me of my own struggles in learning syntax-case. > (define-syntax my-big-class (lambda (stx) (syntax-case stx () ((_ > _field_ ...) #'(class object% (super-new) (my-init _field_) > ...))))) Your mistake is one I have made myself many times: you call my-init as if it were a function, but macro expansion doesn't work like function calling. The `class' macro will be the one in charge after my-big-class. > (define-syntax my-init (lambda [stx] (syntax-case stx () ([_ > _field_] (with-syntax ((getter (datum->syntax #f (string->symbol > (string-append "get-" (symbol->string (syntax->datum > #'_field_))))))) #'[(init-field _field_) (define/public (getter) > _field_)]))))) Here there is no enclosing `class' thus things like `init-field' are errors. > I'm sure theres a simple way around this that I'm missing. I always find it tricky when to convert from syntax to normal scheme, when to convert back and the difference between a list of syntax and a syntax object that contains a list... but in the end I managed to find the right mix: (define-syntax fast-class (lambda (stx) (syntax-case stx () ((_ _field_ ...) (with-syntax (((_getter_ ...) (datum->syntax #f (map (lambda (f) (string->symbol (string-append "get-" (symbol->string f)))) (syntax->datum #'(_field_ ...)) )) )) #'(class object% (super-new) (init-field _field_ ...) (define/public (_getter_) _field_) ...) ))))) (define fast-class1% (fast-class size weight)) (define fast1 (new fast-class1% (size 2) (weight 200))) (send fast1 get-size) (send fast1 get-weight) > Thanks again, You're welcome, Marijn -----BEGIN PGP SIGNATURE----- Version: GnuPG v2.0.18 (GNU/Linux) Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org/ iEUEARECAAYFAk8QCYAACgkQp/VmCx0OL2wXpQCY8ctNFD8lcEQOwzNP6FFPjxrT QACdFUXqhHrwEsgW79d0PPIukZHDHyc= =+9Oa -----END PGP SIGNATURE----- ____________________ Racket Users list: http://lists.racket-lang.org/users