[plt-scheme] Attaching compile-time information to structure types

From: Matthew Flatt (mflatt at cs.utah.edu)
Date: Thu Feb 21 08:30:30 EST 2008

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


Posted on the users mailing list.