badkins
2021-11-26 21:06:44

I’m the sole employee of Lojic Technologies, and for the past few years, I’ve been developing back-end heavy Racket web applications for a client.


badkins
2021-11-27 00:23:37

I’d like to do the following for the return values of a function, but it doesn’t work in this form. Anyone have an idea how to accomplish this? (or/c (values t1 t2) (values t3 t4)) In other words, I’d like to verify that either the function returns two values of types t1 & t2, respectively, or the function returns two values of types t3 & t4, respectively, but not, for example, two values of types t1 & t4.


badkins
2021-11-27 00:25:39

I broke my own rule of preferring to ask questions on Discourse - I’ll post there now, so if possible, answer there…


badkins
2021-11-27 00:28:22

…done <https://racket.discourse.group/t/function-contracts-for-multiple-return-values/284|Discourse link>


sorawee
2021-11-27 00:29:28

I’m not on Discourse, so I will answer here:

One possibility is lifting or/c over -&gt;

(or/c (-&gt; ... (values t1 t2)) (-&gt; ... (values t3 t4)))


badkins
2021-11-27 00:34:29

Hmm… I’m not sure if being in a class complicates things, but I tried the following: (or/c (-&gt;m connection? string? string? (values hash? '())) (-&gt;m connection? string? string? (values #f (listof string?)))) and received an error: get-user-data: broke its own contract\n two of the clauses in the or/c might both match: (-&gt;m connection? string? string? (values hash? (quote ()))) and (-&gt;m connection? string? string? (values #f (listof string?)))


sorawee
2021-11-27 00:34:53

Oh interesting. I do get this error too, so that probably is not the right idea


badkins
2021-11-27 00:35:05

Definitely a good try though - thanks :)


badkins
2021-11-27 00:35:58

My API is questionable anyway, so the proper thing may be to revise the function signature, but I’m still curious about whether it’s possible.


sorawee
2021-11-27 00:36:24

> If there are multiple higher-order contracts, or/c uses contract-first-order-passes? to distinguish between them. More precisely, when an or/c is checked, it first checks all of the flat contracts. If none of them pass, it calls contract-first-order-passes? with each of the higher-order contracts. If only one returns true, or/c uses that contract. If none of them return true, it signals a contract violation. If more than one returns true, it also signals a contract violation. For example, this contract


sorawee
2021-11-27 00:40:46

Apparently, there’s a “dependent range” feature.


badkins
2021-11-27 00:41:15

I can see how distinguishing only on return value adds complexity.


sorawee
2021-11-27 00:44:48

#lang racket (define f/c (-&gt;i ([_ number?]) (values [x (or/c 1 2)] [y (x) (if (= x 1) 11 12)]))) (define/contract (f x) f/c (values 2 12)) (define/contract (g x) f/c (values 1 11)) (define/contract (h x) f/c (values 1 12)) (f 1) ; OK (g 1) ; OK (h 1) ; contract violation


sorawee
2021-11-27 00:45:25

I’m kinda unhappy with this


sorawee
2021-11-27 00:48:30

Apparently, the return arity must be the same.


badkins
2021-11-27 00:49:01

Equal return arity seems reasonable - I’ll fool around with it - thanks!


badkins
2021-11-27 00:56:52

FYI - I posted your solution on Discourse w/ attribution. You’re always so helpful, can I tempt you to joining Discourse? :)


badkins
2021-11-27 00:57:29

I don’t have time to incorporate it into my class right now, but if I can get it to work tomorrow, I’ll mark it as “solved” on Discourse.


sorawee
2021-11-27 01:08:49

Sure, I will join at some point. @spdegabrielle mentioned that there are a lot of seeding posts / experiments at the beginning, and that is why I hesitated to join. But once the forum is past the experimenting phase, I hope things will be more stable and organic, and I would love to join then.