> 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