
@kellysmith12.21 have you seen this issue? it’s relevant to the define-type
thing you’re making https://github.com/racket/racket/issues/3533

@notjack Yep, I’ve seen that issue and I’m hoping that my type definitions will address many of the points discussed.

One thing that I need to figure out is how to handle the fact that Rebellion type forms don’t have access to named constructors and accessors in a define-x-type
form, which is an issue because I need to provide pattern-matching for the sake of implementing struct properties.

I wonder if I can locally construct the appropriate bindings…

huh, what do you mean?

The property-maker procedures of Rebellion have access to the type descriptors, therefore the runtime values for constructors, accessors, &c. My define-type
macro has access to the names of the type components, so it should be possible to have a make-property-maker
form that locally binds all relevant predicates, constructors, &c. to the correct names in the scope of a property association list. This way, define-type
could have a high level interface for property creation that mirrors the #:property
option of struct
.

Hm… I think I could add this functionality to a single type-defining form, like define-tuple-type
, but the case of having to deal with several types at once is a bit trickier

I’ll try some small tests and see what can be done.

Ah, now I see the issue: for my idea to work, I need to have access to all the type descriptors for the parts of an algebraic data type at the same time.

I discovered that the following works, so I might be able to exploit it for my define-type
: #lang racket
(require rebellion/type/tuple)
(define (as-proc one-or-two a b)
(match one-or-two
[(one-proc f) (f a b)]
[(two-procs f g) (f (g a b))]))
(define-tuple-type one-proc (val)
#:property-maker (λ (desc)
(cons (cons prop:procedure as-proc)
(default-tuple-properties desc))))
(define-tuple-type two-procs (val1 val2)
#:property-maker (λ (desc)
(cons (cons prop:procedure as-proc)
(default-tuple-properties desc))))

ah yeah that works because the usage of the defined forms are under a lambda, so the definition of the struct and the implementation of its properties can be mutually recursive with each other

(under a lambda as in, they don’t use things like the accessor/constructor/pattern for the type until they’re called on an instance of the type, by which point the type must have been defined successfully)

I’ll try extending the current define-type
so that users can provide implementations that expand to something like that.

I’ve implemented the extension to define-type
and it works, partially. Although constructors, accessors, and predicates are available for use in property definitions, the match
expanders are not. I’m not sure why this is the case.

Oh, I see. It actually works perfectly, except if you try to define a type in the REPL.

This works exactly as I’d hope: (define-type one-or-two
(one-proc val)
(two-procs val1 val2)
#:property prop:procedure (λ (self a b)
(match self
[(one-proc f) (f a b)]
[(two-procs f g) (f (g a b))])))

Ooh, I could also include a #:derive-property
option that takes generic property makers like default-x-equal+hash
.