Skip to content

Cast should support multiple-value expressions #370

Open
@AlexKnauth

Description

@AlexKnauth

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.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions