[racket] Persistent struct API

From: Sam Tobin-Hochstadt (samth at cs.indiana.edu)
Date: Tue Aug 19 10:52:23 EDT 2014

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.

Sam

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


Posted on the users mailing list.