[racket] Persistent struct API

From: Roman Klochkov (kalimehtar at mail.ru)
Date: Tue Aug 19 11:10:25 EDT 2014

 Serialize is good for one-shot import/export.

By persistence I mean possibility to get objects from persistent storage by reference on-demand.

For example I have facebook-like site:
(persistent-struct user (login password photo ...))

(persistent-struct message (user text seen-by))

If i read concrete message for its text, I don't want to pull all user information for its author and list of users, that have seen the message.

Then I need to make load only references to these users. But when I write (user-login (message-user the-message)), the library must make in field user real struct from reference (and memoize it).

I tried to use impersonator, but it doesn't allow to have own fields in impersonator (and prop:impersonator-of doesn't replace accessors).

generic doesn't add accessors to fields. It only gives common function for different structs.

Tue, 19 Aug 2014 10:52:23 -0400 от Sam Tobin-Hochstadt <samth at cs.indiana.edu>:
>First, for persistence, can you use either prefab structs or the
>serialize library?
>If you can't, what I'd do is implement a generic called `persist`
>using `racket/generic`, and then have all the structs you wanted to be
>persistent implement that generic.
>On Tue, Aug 19, 2014 at 10:45 AM, Roman Klochkov < kalimehtar at mail.ru > wrote:
>> So you mean, that struct should be only struct, not like Common Lisp CLOS or
>> C++ classes, that are "anything with fields".
>> Then I need an advice. I want to make persistent structs. There are several
>> options:
>> 1) Build "`struct?' with #:reader and #:writer options". Then I have to make
>> a struct, redefine accessors and mutators and somehow tell (match ...) that
>> it is not genuine struct (I don't know, how to redefine syntax).
>> 2) Build my own persistent-struct, that is not `struct?'. Then it cannont be
>> used where strut? may be used and I have to write own match-expander.
>> 3) Don't mimic struct. Maybe classes.
>> What would you advice? What is more correct?
>> Tue, 19 Aug 2014 09:35:48 -0400 от Sam Tobin-Hochstadt
>> < samth at cs.indiana.edu >:
>> On Tue, Aug 19, 2014 at 8:32 AM, Roman Klochkov < kalimehtar at mail.ru > wrote:
>>> #lang racket
>>> (require (for-syntax racket racket/struct-info))
>>> (struct foo (a b))
>>> (set! foo-a (let ([old foo-a])
>>> (λ (x) (displayln x) (old x))))
>>> (define t (foo 1 2))
>>> (displayln "Before change")
>>> (match t [(foo a b) a])
>> In this code, `match` looks at `foo`, and sees that it's definitely a
>> struct descriptor created by `struct`, and so that it knows that `t`
>> will really be an instance of `foo`. Then it generates code that uses
>> `unsafe-struct-ref` to extract the fields. That's why it never uses
>> the modified `foo-a`. To check this, it uses the
>> `checked-struct-info?` predicate.
>>> (let-syntax ([foo (extract-struct-info (syntax-local-value #'foo))])
>>> (displayln "After change")
>>> (match t [(foo a b) a]))
>> In this code, `match` can't be sure that `foo` refers to a real
>> struct, so it just treats the struct info as describing some
>> procedures and a predicate, and it generates the "obvious" code, which
>> calls `foo-a`, which you've modified.
>> I could change `match` so that it also uses
>> `variable-reference-mutated?` for all of the identifiers where it uses
>> checked struct info, and so behaves the same in both cases. However,
>> I'd prefer to reject the first program instead, by hiding `foo-a`
>> behind a macro that rejects assignment.
>> Sam
>> --
>> Roman Klochkov

Roman Klochkov
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.racket-lang.org/users/archive/attachments/20140819/06801637/attachment.html>

Posted on the users mailing list.