Thanks Matthias, that makes sense. On Tue, Feb 12, 2019 at 8:50 PM Matthias Felleisen <[email protected]> wrote: > > > > > On Feb 12, 2019, at 5:28 PM, David Storrs <[email protected]> wrote: > > > > On Tue, Feb 12, 2019 at 5:03 PM <[email protected]> wrote: > >>>> > >>>> This is nice for defining abstract types, but it can be pretty > >>>> inconvenient for defining plain old aggregated data types that just have > >>>> a bundle of fields. When defining those types as structs, consider using > >>>> the #:transparent option. This means "use no inspector at all" (roughly) > >>>> and lets `struct-info` Just Work (TM) without any inspector wrangling. > >>>> The downside is that other modules may be able to break your type's > >>>> invariants and possibly circumvent your contracts. > >>> > >>> > >>> That's what I expected, but it doesn't seem to work: > >>> > >>>> (struct person (name age) #:transparent) > >>>> (struct-info person) > >>> #f > >>> #t > >>> > >>> What am I missing? > >> > >> > >> I was stumped on this for a while, but then realized the problem: > >> > >>> (struct-info person) > >> #f > >> #t > >>> (struct-info (person "Alyssa P. Hacker" 42)) > >> #<struct-type:person> > >> #f > > > > Ah, I see. Thanks, I wouldn't have guessed that an instance of a > > struct satisfied `struct-type?` > > > > On the other hand, it seems relatively easy to break these > > protections. Is there a way to prevent that? > > > > ; file test1.rkt > > #lang racket > > (struct person (name age)) > > (provide person) > > > > The line above exports two pieces: the constructor and compile-time > information about the structure, including the functions as you saw. If you > want to protect your invariants, you replace this provide with something like > > (provide (contract-out (person (-> string natural-number/c person?)))) > > See end for a simpler way to test such things. > > > > > ;; end of test1.rkt > > > > > > ; file test2.rkt > > #lang racket > > > > (require "test1.rkt" > > (for-syntax racket > > syntax/parse > > syntax/parse/experimental/template > > syntax/parse/class/struct-id)) > > > > (define p (person 'bob 19)) > > (displayln "required ctor only of a struct defined in another file. > > Can create, is opaque:") > > p > > (displayln "struct-info returns (values #f #t) since the struct isn't > > inspectable here:") > > (struct-info p) > > (define-syntax struct-funcs (syntax-parser [(_ s:struct-id) (template > > (list s.constructor-id s.accessor-id ...))])) > > (define lst (struct-funcs person)) > > (displayln "show list of constructor and accessors that we retrieved > > via macro:") > > lst > > (displayln "Fetch name ('bob) by way of accessor returned through macro:") > > ((second lst) p) > > ; Uncommenting the following will cause compilation to fail, since > > person-name was not exported > > ;(person-name p) > > ;; end of test2.rkt > > > > > > ;; command line: > > $ racket test2.rkt > > required ctor only of a struct defined in another file. Can create, is > > opaque: > > #<person> > > struct-info returns (values #f #t) since the struct isn't inspectable here: > > #f > > #t > > show list of constructor and accessors that we retrieved via macro: > > '(#<procedure:person> #<procedure:person-name> #<procedure:person-age>) > > Fetch name ('bob) by way of accessor returned through macro: > > 'bob > > > > - > > > > > #lang racket > > (module test1 racket > (provide (contract-out (person (-> string natural-number/c person?)))) > (struct person (name age))) > > (module test2 racket > (require (submod ".." test1) > (for-syntax racket > syntax/parse > syntax/parse/experimental/template > syntax/parse/class/struct-id)) > > (define p (person 'bob 19)) > (displayln "required ctor only of a struct defined in another file. Can > create, is opaque:") > p > > (displayln "struct-info returns (values #f #t) since the struct isn't > inspectable here:") > (struct-info p) > > (define-syntax struct-funcs (syntax-parser [(_ s:struct-id) (template (list > s.constructor-id s.accessor-id ...))])) > (define lst (struct-funcs person)) > (displayln "show list of constructor and accessors that we retrieved via > macro:") > lst > > (displayln "Fetch name ('bob) by way of accessor returned through macro:") > ((second lst) p) > > ; Uncommenting the following will cause compilation to fail, since > ; person-name > ) >
-- You received this message because you are subscribed to the Google Groups "Racket Users" group. To unsubscribe from this group and stop receiving emails from it, send an email to [email protected]. For more options, visit https://groups.google.com/d/optout.

