[plt-scheme] Attaching compile-time information to structure types
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