My question is the same as the one asked here, but the answer given there doesn\'t actually work.
I have a bunch of structs inheriting from a parent struct A>
Looking further into the new struct keywords that soegaard mentioned, I think I've come up with a solution that's a bit cleaner and, more importantly, much easier to abstract into a macro (those modules and requires were giving me a really hard time). I thought I'd share it for future reference. Again, this requires one of the nightly Racket builds. I'm using 6.5.0.7.
(Note: the use of case-lambda
over defining keyword arguments here is just my preference.)
#lang racket
(require (for-syntax syntax/transformer))
(struct horse (color)
#:name Horse
#:constructor-name Horse
#:transparent)
(define make-horse
(case-lambda
[() (Horse "black")]
[(color) (Horse color)]))
(define-match-expander horse
; match expander
(λ (pat)
(syntax-case pat ()
[(_ more ...) #'(Horse more ...)]))
; constructor
; edit: changing this to use make-variable-like-transformer,
; as suggested in the comments.
#;(syntax-id-rules ()
[(_ args ...) (make-horse args ...)]
[horse Horse])
(make-variable-like-transformer #'make-horse))
Sample usage:
> (define black-beauty (horse))
> black-beauty
(horse "black")
> (define ginger (horse "red"))
> ginger
(horse "red")
> (match black-beauty
[(horse color) color])
"black"
> (match ginger
[(horse color) color])
"red"
> (horse-color black-beauty)
"black"
> (horse-color ginger)
"red"
In short: instantiation, matching, and accessing fields seem to work as you would expect if you'd just used struct
. The struct id can also be used as an identifier without any syntax issues. I don't really think that part has much practical use, but I thought it was nice.