[plt-scheme] define-struct Style Question
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)]))
; ==>
;
(begin
(define-struct foo (bar moo) #:inspector #f)
(set! make-foo
(let ([make-foo make-foo])
(case-lambda
[(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.