Description
Cast should be able to support multiple-value expressions, such as
(cast (values 1 2) (values Integer Integer))
Is there any reusable code for attaching contracts to multi-value expressions like this? I noticed that these two ways of doing that do very different things:
(define/contract (f)
(-> (values number? number?))
5)
(define (g)
(with-contract g #:results [number? number?] 5))
One raises a contract blame error specifying the function that violated the contract, the numbers of values expected and received, the contract and the context within the contract that was violated, where the contract came from, and who is to blame for violating the contract.
The other raises a result arity mismatch error specifying the numbers of values expected and received, but without any contract or blame information. I imagine this can be implemented much more easily and efficiently, without needing call-with-values
, but it is a much worse error message.
For multi-value expressions like (cast (values 1 2) (values Integer Integer))
, which strategy should it use? Is there any reusable code for either strategy? The code for the first strategy in racket/contract/private/arrow-val-first.rkt
and racket/contract/private/arrow-higher-order.rkt
seems specific to function contracts, and the with-contract
form for the second strategy doesn't seem to allow specifying the negative party for the blame.