Thanks Matthias, that makes sense.

On Tue, Feb 12, 2019 at 8:50 PM Matthias Felleisen
<matth...@felleisen.org> wrote:
>
>
>
> > On Feb 12, 2019, at 5:28 PM, David Storrs <david.sto...@gmail.com> wrote:
> >
> > On Tue, Feb 12, 2019 at 5:03 PM <jackhfi...@gmail.com> 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 racket-users+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Reply via email to