> 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.