Actually, this macro doesn't quite work, because it uses the #lang racket version of define-struct instead of the version appropriate to whichever language the student is in: Beginning SL, Intermediate SL, or Advanced SL.
How would I fix that? Todd On Sun, Jul 25, 2010 at 4:16 PM, Todd O'Bryan <[email protected]> wrote: > Because it can get really annoying to have to retrofit a whole program > when you add a bit of extra state to a world, Barry Brown first > suggested and then I--having completely forgotten about Barry's > suggestion--re-suggested that worlds include functional update > functions, so that changing a single field in a world didn't require > students to include boilerplate code to leave all the other fields > unchanged. > > I think the following macro just about does this: > > #lang racket > (provide define-world) > > (define-for-syntax (build-name id . parts) > (datum->syntax > id > (string->symbol > (apply string-append > (map (lambda (p) > (cond > [(syntax? p) (symbol->string (syntax-e p))] > [(symbol? p) (symbol->string p)] > [(string? p) p])) > parts))) > id)) > > (define-for-syntax (updater id fields field) > (let ([name (build-name id id '- 'update- field)] > [instance (build-name id 'a- id)] > [constructor (build-name id 'make- id)]) > `(define (,name ,instance val) > (,constructor ,@(for/list ([f fields]) > (if (equal? f field) > 'val > `(,(build-name id id '- f) ,instance))))))) > > (define-syntax (define-world stx) > (syntax-case stx () > [(_ id fields) > (let ([field-names (syntax->list #'fields)]) > #`(begin > (define-struct id fields) > #,@(for/list ([f field-names]) > (updater #'id field-names f))))])) > > How do I provide tests, and is there any chance something like this > could end up in 2htdp/universe? > > Todd > _________________________________________________ For list-related administrative tasks: http://lists.racket-lang.org/listinfo/users

