[plt-scheme] Contracts and (multiple-return-)values

From: David Brooks (djb.untyped at googlemail.com)
Date: Thu Nov 26 10:47:32 EST 2009

Hi PLTers,

I've just had a bit of grief with the intersection between procedures  
returning multiple values, their contracts, and my careless  
programming. (I'm sure this is a question with a Noddy answer, but  
I've not drummed up anything in my googling.)

I wrote a procedure returning multiple values: (values a b), where "a"  
is a struct and "b" is a list of structs of type "c". I gave this  
procedure a contract accordingly:

[my-proc (-> (values a? (listof c?)))]

After getting bored of all the different "let" and "let-values"  
blocks, I decided to change the procedure to return (cons a b).  
However, I forgot to change the contract (d'oh!), so when I ran my  
code I got an error of the form:

context (lexical binding) expected 2 values, received 1 value:  
(#(struct:a ...) #(struct:c ...) #(struct:c ...) ...

I spent a little while examining all my lexical assignments procedure  
return-types, before I realised this was a contract violation, but one  
that wasn't being flagged as such.

So my questions are
[1] does the contract system offer any protection against misuse of  
"values"? If so, how do I use it? If not, is there an interesting  
technical reason why not?
or [2] is there any way I can get more meaningful error messages if I  
am stupid enough to repeat my mistake?

David Brooks

Posted on the users mailing list.