[racket] Making a contract between a function and "the world in general"

From: Neil Toronto (neil.toronto at gmail.com)
Date: Sat Oct 8 12:48:07 EDT 2011

On 10/08/2011 10:12 AM, Matthias Felleisen wrote:
>
> (1) I do not understand Neil's problem. Say I have module A and
> want to protect its exports from abuses by clients, say module B,
> why do you use define/contract at all? The define/contract form
> is for splitting modules into module-lets -- in case your module
> is too large and you can't manage invariants in your head.

Which now I see that you can *infer* from the docs, if you already sort 
of know this. They're kinda jagony. But now I understand, so thank you.

The thing is, define/contract has a huge advantage that contract-out 
doesn't have: it puts all the invariants at the function definition, 
right before the code that relies on them. I suppose I could get the 
same effect with a contract-out right before the function definition (or 
write a define/provide macro). But I think the style guidelines say this 
is bad, and I don't like scattering provides throughout code.

> If you
> believe that this is true for even small modules, I urge you to
> use Typed Racket. That's the better solution and real soon now
> TR will allow you to add contracts on top of types at provides.

I would love to, if not for all the keyword arguments. :( That is 
seriously the only thing keeping me from making PLoT into a typed library.

> (2) I object to
>
>   provide-with-whatever-contract-you-already-have
>
> because I think programmers should explicitly state what
> they want (if they want something logical).

I can't explicitly say what I want right now, and I think it's logical.

Would the following be explicit enough?

     (provide (contract-out real-id))

     ; ... more code ...

     (define/contract (real-id x) (real? . -> . real?)
       x)

Or (provide (lift-contract real-id)) might be even better.

Thanks,
Neil T


Posted on the users mailing list.