Hi all, Sometimes when defining struct types it is useful to have fields which are essentially "private" to the module (fields whose accessors/mutators are not exported from the module.) I want these fields to be initialized automatically with arbitrary values generated at construction time.
Here are some methods I've considered and what I don't like about them: 1) Create a wrapper around the generated constructor which provides the correct values for the private fields: (provide make-mystruct1 mystruct1-public) (struct mystruct1 (public private)) (define (make-mystruct1 public) (mystruct1 public (get-new-private))) The downside of this method is that you can't allow arbitrary subtypes outside the module because they'd have to supply an invalid value for the private field. 2) To fix the subtype constructor problem, we could make the fields #:auto and provide a separate init procedure: (provide mystruct2 make-mystruct2 init-mystruct2 mystruct2-public) (struct mystruct2 (public [private #:auto]) #:constructor-name make-mystruct2 #:mutable) (define (init-mystruct2 m2) (set-mystruct2-private! m2 (get-new-private))) Now subtype constructors need not specify a bogus value for the private field, but the init procedure is not elegant. (Wrappers could be defined for each type/subtype constructor which also call the init procedure.) 3) Specify a guard procedure: (provide mystruct3 make-mystruct3 mystruct3-public) (struct mystruct3 (public private) #:constructor-name make-mystruct3 #:guard (lambda (public private-ignored name) (values public (get-new-private)))) Here the guard procedure provides a valid value for the private field, but unfortunately the constructor and subtype constructors still need to take a bogus value for the private field (which will be ignored in the guard.) Like the init procedure method, that could be fixed by having a separate wrapper for each type/subtype constructor. Have I missed a method? What I'd really like is to be able to specify the private fields as #:auto so they need not be given as constructor arguments but still have a guard procedure return them. Something like: (provide mystruct5 make-mystruct5 mystruct5-public) (struct mystruct5 (public [private #:auto]) #:constructor-name make-mystruct5 #:guard* (lambda (public name) (values public (get-new-private)))) This would allow me to completely control the private field within my module while not requiring bogus/ignored constructor arguments nor requiring wrappers. (If there is nothing like this currently, and others think it would be good to have, I'd be willing to take a stab at implementing it.) Thanks. David ____________________ Racket Users list: http://lists.racket-lang.org/users