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.

Reply via email to