[plt-scheme] Attaching compile-time information to structure types
I've changed `scheme/struct-info' to export `struct:struct-info'.
Ryan's solution might be easier to use in general, though.
Matthew
At Thu, 21 Feb 2008 08:20:43 -0500, Ryan Culpepper wrote:
> Dave Gurnell wrote:
> > Hi all,
> >
> > I have another macrological question,related to but separate from my
> > last one about my SQL wrapper.
> >
> > I have a macro, define-persistent-struct, that defines a struct that can
> > be serialized to a database. define-persistent-struct basically works
> > like define-struct, except it creates a few more variables. For example:
> >
> > (define-persistent-struct person ([name type:string] [age
> > type:integer]))
> >
> > would define all the things that define-struct would defined:
> >
> > person, struct:person, make-person, person?, person-age, person-name
> > and so on...
> >
> > plus some metadata that gets attached via a property:
> >
> > entity:person, attr:person-age, attr:person-name ...
> >
> > I'd like to attach some extra compile-time information to person so I
> > can retrieve the bindings for entity:person and attr:whatever in macros.
> >
> > I hacked something up by subtyping struct-info from
> > scheme/private/struct-info.ss and adding extra fields to it. This works
> > for the most part, but it is obviously not the recommended approach as
> > struct:struct-info isn't provided from struct-info.ss. I've also had
> > problems using scheme/match in certain cases.
> >
> > Can anyone point me in the right direction?
>
> The easiest way that comes to mind is to use a compile-time table
> (module-identifier-mapping) that maps struct names to the additional
> information you want.
>
> The code would look something like the following (error-handling code
> omitted, treats types as symbols, etc):
>
> (module persistent-struct scheme/base
> (require (for-syntax scheme/base)
> (for-syntax syntax/boundmap))
>
> (define-for-syntax the-table (make-module-identifier-mapping))
>
> (define-syntax define-persistent-struct
> (syntax-rules ()
> [(define-persistent-struct name ([field type] ...))
> (begin (define-struct name (field ...))
> (begin-for-syntax
> (module-identifier-mapping-put! the-table #'name
> (list (cons 'field 'type) ...))))]))
>
> (define-syntax (type-of-field stx)
> (syntax-case stx ()
> [(type-of-field struct field)
> (let* ([info (module-identifier-mapping-get the-table #'struct)]
> [type (cdr (assq (syntax->datum #'field) info))])
> (with-syntax ([type type])
> #'(quote type)))])))
>
> (define-persistent-struct S ([x int] [y bool]))
> (type-of-field S x) ;; => 'int
>
> Ryan
>
> > _________________________________________________
> > For list-related administrative tasks:
> > http://list.cs.brown.edu/mailman/listinfo/plt-scheme
>
> _________________________________________________
> For list-related administrative tasks:
> http://list.cs.brown.edu/mailman/listinfo/plt-scheme