[plt-scheme] define-struct Style Question

From: Matthias Felleisen (matthias at ccs.neu.edu)
Date: Fri Nov 30 14:24:20 EST 2007

On Nov 30, 2007, at 2:12 PM, Doug Williams wrote:

> I often use structs as the basis for an abstraction.  They are  
> simple, convenient, and built into PLT Scheme.  However, more often  
> than not, I want some slight variation on the normally generated  
> interface.  For example, I often want a different constructor  
> because some of the slots are computed or are internal to the  
> abstraction.  In the past I have been using make-struct-type in  
> these cases (with <name>-constructor) and coding a new make-<name>  
> function and generating the field accessors and mutators using make- 
> struct-field-field-accessor or make-struct-field-mutator (or coding  
> accessor or mutator functions if there do more than just get or set  
> a slot).  This works, but it's a pain and results in a lot of  
> repetitive boilerplate kind of code.  [And, I can't easily extent  
> the struct type with new sub-types.  (There seems to be additional  
> syntax information generated by define-struct that isn't generated  
> by make-struct-type.)  But, I'm okay with that.  I tend to 'move up  
> to' classes if I need inheritance, etc.]
> I've seen that some people use define-struct and then create new  
> constructors (or accessors and mutators) that are renamed when they  
> are provided by the module containing them.  This works, but you  
> have different name within the module than externally.  [This  
> difference is often minimized to just a prefix added.]
> I am leaning toward changing my style to the use of define-struct  
> with renames to provide struct-based abstractions.  But, are there  
> other methods that might be better.  [Generally, better to me means  
> more readable and maintainable.]

Have you considered designing a define-struct sub-language that  
accommodates this second style (my preference, too), plus the  
following variation on theme 2:

#lang scheme

; example:
; (define-struct/default foo (bar [moo (+ bar 10)]))
; ==>
   (define-struct foo (bar moo) #:inspector #f)
   (set! make-foo
         (let ([make-foo make-foo])
             [(bar) (make-foo bar (+ bar 10))]
             [(bar moo) (make-foo bar moo)]))))

(define foo1 (make-foo 10))
(define foo2 (make-foo 10 20))

I recommend evolving this language as you go.

Posted on the users mailing list.