What do you mean by normalizing
? edit: Ok, I think I understand what you mean: things like (max 0 x-arg)
say
Dictionary for construction with a hierarchy: The nice thing about dictionaries is that it makes it easy to pass values from child struct to parent while constructing: each child consumes the entries it needs and passes the remaining dictionary to the parent constructor. If the top constructor obtains a non-empty dict after consuming its entries, raise an exception with the remaining keys. I suppose the class system does something similar?
huh, like you have some structs in an inheritance hierarchy and instead of giving the constructors positional arguments or keyword arguments, you just give them a big ol dictionary?
i’m also often using hierarchy construction in this way: #lang racket
(struct A (a) #:transparent)
(struct B A (b) #:transparent)
(struct C B (c d) #:transparent)
(define (make-A #:constructor [constructor A]
#:a [a 'a]
. other-args)
(apply constructor a other-args))
(define (make-B #:constructor [constructor B]
#:a [a 'a]
#:b [b 'b]
. other-args)
(apply make-A #:constructor constructor
#:a a
b
other-args))
(define (make-C #:constructor [constructor C]
#:a [a 'a]
#:b [b 'b]
#:c [c 'c]
#:d [d 'd]
. other-args)
(apply make-B #:constructor constructor
#:a a
#:b b
c d
other-args))
(make-C #:c 'cc #:a 'aa #:b 'bb)
Dictionaries can make this process nicer, but there’s no syntactic check
@notjack Yes, though more precisely I turn the dictionary values into positional arguments
(Code above edited, it was rather buggy…) Dicts can prevent a lot of the code duplication easily.
Here’s an example using dictionaries: https://gist.github.com/Metaxal/a56db8212087eccfc4945fa885efbb4e
yeah, so like if you’ve got a case-insensitive string user ID, a struct like (struct user-id (string))
could case fold the ID string at construction time
I use them in Gregor both for default values and, I suppose, a kind of normalization, though I think it would be more straightforwardly described as separating the public interface (of which the constructor is part) from the data structure’s underlying representation.
I think it’s worth mentioning that when I provide my own constructor, I like to provide my own pattern match expander, too, and the dance you have to do to export the custom constructor and match expander so that they are properly rackety is a bit of a bear.