[plt-scheme] Attaching contracts to unit exports

From: John Clements (clements at brinckerhoff.org)
Date: Fri Mar 2 16:36:39 EST 2007

On Mar 2, 2007, at 1:04 PM, Paulo J. Matos wrote:

> On 3/2/07, John Clements <clements at brinckerhoff.org> wrote:
>> The negative position is the left side of the arrow. The positive
>> position is the right side of the arrow.  Since these positions can
>> themselves be arrow types, you can talk about the positive position
>> of a negative position.  In this example
>> ((a -> b) -> (c -> d))
>> The letter 'b' occurs in the positive position of a negative
>> position.  The letter 'c' appears in the negative position of a
>> positive position.
>> The distinction here is on how many "negative links" you have to
>> follow to get to the given type.  In this type, 'b' and 'c' both
>> require following one negative link. That means that the function's
>> caller is responsible, since one is an odd number.  'a' requires
>> following two negative links.  Two is an even number, so the function
>> itself is responsible .  'd' requires following zero negative links,
>> so again the function itself is responsible.
> That's crystal clear to me now and it makes sense with regard to the
> paper. But it still puzzles me what's the negative-blame or
> positive-blame in the contract API. Since they are symbols I can only
> imagine one is the symbol identifying the function and the other is a
> symbol identifying the callers. First, I cannot see how one can
> identify the latter when writing the contract code (this should be
> done at run time)

Now you understand why there are not currently built-in forms for  
contracts on units; with modules, it's always possible to associate a  
call to a contract-protected thing with source positions for both  
caller and callee.

> and then I cannot understand why call it positive
> blame or negative blame. Well, I just ran this code:
> (module test mzscheme
>  (require (lib "contract.ss"))
>  (define greater-than-nine?
>    (lambda (n)
>      (and (integer? n) (> n 9))))
>  (define between-zero-and-ninety-nine?
>    (lambda (n)
>      (<= 0 n 99)))
>  (define g
>    (lambda (f) (f 0)))
>  (define g/contract
>    (contract
>     ((greater-than-nine? . -> . between-zero-and-ninety-nine?) . -> .
> between-zero-and-ninety-nine?)
>     g
>     'positive-blame 'negative-blame)))
>> (g/contract (lambda (x) x))
> I get a positive-blame, when changing g to be (lambda (f) (f 10))  
> and then
>> (g/contract (lambda (x) -10))
> I get negative-blame. So, can I deduce that you can a positive-blame
> when blaming the function to which the contract is attached and a
> negative blame when blaming its caller?
> If yes, why call this positive or negative? It doesn't seem to have
> any thing to do about being on the right or left side of the arrow.

Sure it does; in the simple case of a contract like a? . -> . b?,  
then the callee is blamed for failures on the positive side of the  
arrow, and the caller for failures on the negative side of the  
arrow.  So it's quite natural to extend this and call all caller  
blamings "negative".

Always happy to be corrected,

John Clements

-------------- next part --------------
A non-text attachment was scrubbed...
Name: smime.p7s
Type: application/pkcs7-signature
Size: 2484 bytes
Desc: not available
URL: <http://lists.racket-lang.org/users/archive/attachments/20070302/28de1c0a/attachment.p7s>

Posted on the users mailing list.