[racket] writing a define-world macro

From: Todd O'Bryan (toddobryan at gmail.com)
Date: Sun Jul 25 16:23:15 EDT 2010

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?


On Sun, Jul 25, 2010 at 4:16 PM, Todd O'Bryan <toddobryan at gmail.com> 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

Posted on the users mailing list.