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

From: Dave Gurnell (d.j.gurnell at gmail.com)
Date: Thu Feb 21 11:33:18 EST 2008

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



Posted on the users mailing list.