Have you considered classes instead of structs? -- Matthias
On Nov 9, 2013, at 12:50 PM, David T. Pierson wrote: > 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 ____________________ Racket Users list: http://lists.racket-lang.org/users