Just write a wrapper:
(struct struct-id (abcd) #:constructor-name struct-id* #:guard (lambda (abcd type-name) do-stuff)) (define (struct-id (a) (b) (c) (d 'default-value)) (struct-id* abcd))
This gives you a constructor in which all field arguments are optional. Defining them in this way, rather than using dot notation, eliminates the need to parse the rest argument.
I have provided a default value for d , and Racket will do the default value of the remaining #f .
You can also define it to have keyword arguments:
(define (struct-id
In the above case, #:c is a required argument because I settled on parentheses, I provided 'default as the 'default value of d , and the rest will have a default value of #f , which this time should be explicitly provided. Keywords can be passed to the constructor in any order.
If you use many structures, you might need a macro to define a wrapper for you:
(begin-for-syntax (require (planet jphelps/loop)) ;; Installs a library on first use. Be patient. (define stx-symbol->string (compose symbol->string syntax->datum)) (define (make-constructor-name stx-name) (datum->syntax stx-name (string->symbol (string-append (stx-symbol->string stx-name) "*")))) (define (stx-symbol->stx-keyword stx-symbol) (datum->syntax stx-symbol (string->keyword (symbol->string (syntax->datum stx-symbol)))))) (define-syntax struct* (lambda (stx) (syntax-case stx () ((_ struct-name fields . options)
Then define your structures as follows:
(struct* struct-id (abcd) #:guard whatever)
You will automatically receive a constructor with keywords named struct-id* , which will not conflict with the names generated by the form struct .
EDIT
Obviously, the above macro, since it was originally written, did not work in module-based programs. I tested it only on REPL, which is more like Lisp, since you are allowed to override everything. This disguised the fact of adding the struct #:constructor-name option and an additional constructor name instead of overriding the name of an existing constructor. This is despite the fact that the #:extra-constructor-name option exists, which also creates an additional constructor name.
Fixing this problem so that it is completely seamless would require re-implementing the entire struct macro. You will have to rename the structure, and then create not only the constructor, but also all the accessors and mutators. An easier way would be to generate a constructor with a different name from the original constructor. I modified the code above to implement this workaround.