[racket] `immutable?` for `struct`s?

From: Carl Eastlund (carl.eastlund at gmail.com)
Date: Sat Jan 25 18:14:39 EST 2014

skipped? = #t can only arise if some struct type in the hierarchy is
opaque, which would mean struct? returns #f.  If you only care about types
that satisfy struct?, you should be able to safely ignore skipped?, if I
understand it correctly.

Carl Eastlund


On Sat, Jan 25, 2014 at 6:07 PM, Greg Hendershott <greghendershott at gmail.com
> wrote:

> > flaw: If an immutable struct is derived from a mutable one, my
> > predicate will (as written) incorrectly report it as immutable.
> > Instead I need to walk the chain of super-types, and check that all
> > are immutable. I'll work on this more...
>
> Here's where I ended up for now.
>
> Although I don't understand how/when/why skipped? = #t would arise,
> I'm pretty sure that if it does arise, I can't make any assertion
> about immutability and should err on the side of saying "no".
>
> Will sleep on this. Would welcome feedback if anyone has any.
>
> ;; As documented, `immutable?` does not work with `struct`s. Define a
> ;; predicate that does:
> (define (immutable-struct? v)
>   (define-values (st skipped?) (struct-info v))
>   (and (not skipped?) ;unless most-specific type, can't assert immutability
>        (immutable-struct-type? st)))
>
> (define (immutable-struct-type? st)
>   (define-values (name init-field-cnt auto-field-cnt
>                   accessor-proc mutator-proc
>                   immutable-k-list
>                   super-type skipped?) (struct-type-info st))
>   ;; A struct-type is immutable if all its fields are immutable, AND
>   ;; all its super struct-types are immutable.
>   (and (not skipped?) ;unless most-specific type, can't assert immutability
>        (= (+ init-field-cnt auto-field-cnt)
>           (length immutable-k-list))
>        (or (not super-type)
>            (immutable-struct-type? super-type))))
>
> (module+ test
>   (struct mutable (fld) #:mutable #:transparent)
>   (define m (mutable 0))
>   (check-false (immutable-struct? m))
>
>   (struct mutable:immutable mutable (fld2) #:transparent)
>   (define m:i (mutable:immutable 0 1))
>   (check-false (immutable-struct? m:i))
>
>   (struct immutable (fld) #:transparent)
>   (define i (immutable 0))
>   (check-true (immutable-struct? i))
>
>   (struct immutable:immutable immutable (fld2) #:transparent)
>   (define i:i (immutable:immutable 0 1))
>   (check-true (immutable-struct? i:i)))
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.racket-lang.org/users/archive/attachments/20140125/b9729683/attachment.html>

Posted on the users mailing list.