[racket] Contracts and submodules

From: Greg Hendershott (greghendershott at gmail.com)
Date: Thu Nov 29 22:29:14 EST 2012

AFIK these subtleties of contracts and modules arise with
`provide/contract' -- by saying that the function should only use a
contract outside the module (or submodule).

But I prefer to use `define/contract'. For one thing, I think it's
easier and more-maintainable to group the contract near/with its
function in the source. But I also prefer it on the starting
assumption that if a procedure is worth contracting at all, it's worth
contracting all the time -- inside the module as well as outside.

I understand there are two reasons why this might not be the case:

- It might be desirable to violate the contract as an internal
implementation detail. But in that case, which I've not yet
encountered myself, I could also define a plain version plus
define/contract a wrapper version (which IIUC is essentially what
provide/contract is doing for you via a "chaperon"), or use
provide/contract just in such a case.

- It might be desirable for performance. But I think the preferable
answer here would be to make contracts less slow. Which it seems like
they could be in the simple cases, Which simple cases seem to be
nearly all the cases in my own code to-date.

This is my personal view/experience but I don't know if it's shared by
others. For example I think some people use modules as a barrier of
abstraction roughly like how people would use classes in C++ or Java.
Although that idea hasn't really clicked for me, I understand and
appreciate that.

Regardless, I do wish contracts could be (much, much) faster, and
lately I've doinked around with some experiments you could call "term
sheets". The idea being to get the same declarative style of contracts
but with speed comparable to handwritten checks. I wish I were smart
enough to help do this as an optimization to the real contract system
(if that's even possible).

Maybe the long-term vision is, "use Typed Racket instead", but I think
even in that case TR needs to interoperate safely with untyped code
for some time to come ... which it does using contracts.

On Thu, Nov 29, 2012 at 7:59 PM, Harry Spier <vasishtha.spier at gmail.com> wrote:
> Dear list members,
>
> Case 1 below doesn't give a contract violation but case 2 does.  Is
> this desired behavour or is it a bug?
>
> In DrRacket
> Case 1
> ---------
> #lang racket
> (provide (contract-out [ident-number (-> number? number?)]))
> (define (ident-number x)  x)
> (module+ main
>   (ident-number 'a))
>
>> 'a
>
>
> Case 2
> ------------
> #lang racket
> (provide (contract-out [ident-number (-> number? number?)]))
> (define (ident-number x)  x)
> (module+ main
>   (require (submod ".."))
>   (ident-number 'a))
>
>>
>  ident-number: contract violation
>  expected: number?
>  given: 'a
>  in: the 1st argument of
>       (-> number? number?)
>  contract from:
>       c:\users\harry\ocr_project\test2.rkt
>  blaming:
>       (c:\users\harry\ocr_project\test2.rkt main)
>  at: c:\users\harry\ocr_project\test2.rkt:2.24
>
> Thanks,
> Harry Spier
> ____________________
>   Racket Users list:
>   http://lists.racket-lang.org/users

Posted on the users mailing list.