notjack
2021-1-4 10:04:47

@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


kellysmith12.21
2021-1-4 13:26:04

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


kellysmith12.21
2021-1-4 13:30:55

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.


kellysmith12.21
2021-1-4 13:32:18

I wonder if I can locally construct the appropriate bindings…


notjack
2021-1-4 14:04:32

huh, what do you mean?


kellysmith12.21
2021-1-4 14:12:57

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.


kellysmith12.21
2021-1-4 14:49:56

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


kellysmith12.21
2021-1-4 14:51:32

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


kellysmith12.21
2021-1-4 15:02:53

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.


kellysmith12.21
2021-1-5 00:34:56

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))))


notjack
2021-1-5 01:11:51

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


notjack
2021-1-5 01:12:46

(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)


kellysmith12.21
2021-1-5 01:23:35

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


kellysmith12.21
2021-1-5 02:17:36

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.


kellysmith12.21
2021-1-5 02:27:46

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


kellysmith12.21
2021-1-5 02:28:28

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))])))


kellysmith12.21
2021-1-5 04:06:34

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