Of course, if you're okay with a longer email. Before that, thank you both for volunteering your time to code something out. I enjoyed running into a `define-module-boundary-contract` in the wild for the first time.
I sometimes print output in a (read)able form because I like analyzing my logs. The data I print includes prefab structures, with type ids matching the topic they cover or the statements they make. You can see that I declare prefab structure (sub)types cutely labeled "messages" here. [1] The idea is that I can either print (for example) a $package:output:built instance as a localized string, or just toss the instance itself into writeln. When I read instances back from a port, the struct accessors will help me filter and match. Hopefully all this shows where my head is. Now for the problem. Look at [2], but don't worry about what it means. I just wanted you to see the constructor call in the exception handler. If I made a mistake and wrote that line such the exception was placed directly in the instance, then I wouldn't be able to (read) that instance back later! I cannot allow #<...> forms in my output, or some symbol soup that happens to be readable, but doesn't constitute the value it used to be. TL;DR I want to protect the invariant `(equal? V (read (open-input-string (~s V))))` for each V I print to an output port. Finally, as to why I didn't want the module boundary contract. The module that declares prefab structure types is also primarily responsible for creating all instances of those types. I rarely cross module boundaries when applying the constructors. [1]: https://github.com/zyrolasting/xiden/blob/master/package.rkt#L49 [2]: https://github.com/zyrolasting/xiden/blob/master/security.rkt#L100 On 5/9/21 8:02 PM, Philip McGrath wrote: > Here's another minimally-tested sample implementation. A more robust solution > might try to chaperone the struct type, as well, to protect reflective access > to the constructor—but I wonder if that really makes sense when you are > working with prefab structs. If you can explain more about your requirements, > it might be possible to suggest better approaches. > > On Sun, May 9, 2021 at 7:57 PM Ryan Culpepper <[email protected]> wrote: > >> I'm not clear on what constraints you're working under with respect to >> modules, but hopefully you can adapt this to your needs. >> >> One option is to use a combination of `define-module-boundary-contract` (or >> `define/contract`) and `define-match-expander` to bind a name that can be >> used as a contracted constructor and as a match pattern. (If you want to >> extend the struct type, though, you still need to use the real one.) >> >> Another option would be to "forge" a new compile-time struct-info based on >> the original struct-info but replacing the constructor. >> >> Minimally tested sample implementations attached. >> >> Ryan >> >> On Mon, May 10, 2021 at 12:23 AM Sage Gerard <[email protected]> wrote: >> >>> I have a project with 57 prefab structure types. I need to construct >>> instances using a local contract (module level contracts do not fit my >>> needs here). Since I cannot define guards, the solution is easy enough. >>> >>> (struct foo (num) #:prefab) >>> (define/contract make-foo (-> real? foo?) foo) >>> >>> Problem: I already have a few hundred constructor calls without contracts. >>> I could either A) rewrite them all to use contracted constructors, or B) >>> attach local contracts in a sweet spot so that I don't have to rewrite >>> anything else. >>> >>> I prefer option B, but it doesn't look like I can attach a local contract >>> to a constructor with `struct` alone, or even with an impersonator. When I >>> hack around to rebind or hide the constructor's identifier, I break >>> compatibility with `match` and `defstruct*`. >>> >>> If you were in my position, what would you do? >>> >>> -- >>> >>> ~slg >>> >>> -- >>> You received this message because you are subscribed to the Google Groups >>> "Racket Users" group. >>> To unsubscribe from this group and stop receiving emails from it, send an >>> email to [email protected]. >>> To view this discussion on the web visit >>> [https://groups.google.com/d/msgid/racket-users/0a16cfbe-4789-a939-796e-5f6f9da21626%40sagegerard.com](https://groups.google.com/d/msgid/racket-users/0a16cfbe-4789-a939-796e-5f6f9da21626%40sagegerard.com?utm_medium=email&utm_source=footer). >> >> -- >> You received this message because you are subscribed to the Google Groups >> "Racket Users" group. >> To unsubscribe from this group and stop receiving emails from it, send an >> email to [email protected]. >> To view this discussion on the web visit >> [https://groups.google.com/d/msgid/racket-users/CANy33qmngGoVoAok6%2BR885jkh8MroMqYHpOd6XtjCSH7iiESQA%40mail.gmail.com](https://groups.google.com/d/msgid/racket-users/CANy33qmngGoVoAok6%2BR885jkh8MroMqYHpOd6XtjCSH7iiESQA%40mail.gmail.com?utm_medium=email&utm_source=footer). -- ~slg -- You received this message because you are subscribed to the Google Groups "Racket Users" group. To unsubscribe from this group and stop receiving emails from it, send an email to [email protected]. To view this discussion on the web visit https://groups.google.com/d/msgid/racket-users/a28f5e1e-93e2-d16d-48ab-32168dd42745%40sagegerard.com.

