[plt-scheme] Attaching compile-time information to structure types
Thanks for your responses. I took your advice and used Ryan's
suggestion. The identifier map is a useful tool of which I was
previously unaware. Preliminary tests show everything working as
expected.
Cheers!
-- Dave
> 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