[plt-scheme] Questions about (contract ...) form

From: Robby Findler (robby at cs.uchicago.edu)
Date: Sun Nov 6 15:32:35 EST 2005

At a high level `contract' is used as the definition of some kind of
boundary between "things". In the case of provide/contract (which
expands to contract), the things are modules. In the case of
define/contract, the things are definitions (but define doesn't work as
well as a module leading to some strange things with define/contract
sometimes ... but that's neither here nor there). So the first question
to answer is what the "things" are.

At Sun, 6 Nov 2005 14:44:47 -0500, Richard Cobbe wrote:
> I need to use the (contract ...) form in a macro I'm writing, and I've
> got a couple of questions about its use.  Here's the setting:
> 
> (define-syntax stream-cons
>   (syntax-rules ()
>     [(_ a d)
>      (make-stream:cell a (delay d))]))
> 
> (Yes, I know about SRFI 40, but even streams won't work for my
> application.)
> 
> I'd like to wrap a contract around (the value of) d to ensure that it's
> a stream, and of course I want to check this contract only when the
> stream's cdr is forced.  I'm imagining changing the macro template to
> read (make-stream:cell a (delay (contract stream? d positive-blame
>                                                     negative-blame
>                                                     contract-source)))
> instead.
> 
> First, the manual specifies that positive-blame and negative-blame must
> be symbols indicating where blame is to be assigned.
> 
>   a) Are these symbols supposed to be module names?

They are the names of "things". If your boundaries are module
boundaries then yes. Otherwise, no.

>   b) Is negative-blame meaningful when the value in question is not a
>      function?

Yes. The contract language is set up so that each contract should be
between two parties (this also works for N parties, when you think of
N+1 pairwise contracts with some common one "thing" that connects them
together -- if you need something like that directly we can talk more
about it.). One party is responsible the value initially and things
that flow in the first direction (positive) and the other is
responsible for values that flow back into the original place. So, in
the case of functions, positive is for the function itself (it's arity)
and for results of the function. Negative is for arguments to the
function (or results of argument functions, etc).

But there are other kinds of connections between "things" (beyond
functions) that allow backwards flow.

>   c) If these symbols are supposed to be module names, how do I get the
>      name of the module which contains the use of stream-cons?  I've
>      seen syntax-source-module, but that can potentially return a module
>      path index, and it's not clear how to extract the module name from
>      that.

See module-source-as-symbol in mzlib/private/contract-helpers for what
provide/contract does.

> Second, the manual says that "contract-source, if specified, indicates
> where the contract was assumed."  What does it mean to assume a
> contract?

Assume as in "to take it on", not assume as in "prove an implication".
Bad choice of words, perhaps?

> Or is there a better way to do this altogether?

I guess provide/contract doesn't work for you because you want to
export a macro?

Robby


Posted on the users mailing list.