[plt-scheme] Contract Error Message
On Mon, Jul 20, 2009 at 3:33 PM, YC<yinso.chen at gmail.com> wrote:
>
> On Mon, Jul 20, 2009 at 12:22 PM, David Van Horn <dvanhorn at ccs.neu.edu>
> wrote:
>> I don't want to change the contract language, so I must be confused about
>> what a "higher-order" contract is -- which I guessed was anything
>> satisfying:
>>
>> (lambda (x)
>> (and (contract? x)
>> (not (flat-contract? x)))
>>
>> But it seems the bug here is actually in the docs.
>>
>> "Takes any number of predicates and higher-order contracts"
>>
>> The higher-order part should be dropped, right?
>
> I agree that the doc seem ambiguous on the higher contract point. IIUC, or/c
> is a higher order contract itself, and accepts regular contracts (including
> constants, predicates, flat contracts) and higher order contracts such as
> another or/c, listof, etc.
No, or/c is not a higher order contract. It is a higher order
function that produces a (possibly higher-order) contract.
A higher order contract is one that wraps a function and delays
contract checking to function application time. For instance,
(string? integer? . -> . string?) is a contract one could give to
substring. It can't check the inputs and outputs right away (as there
are none inherent in the function), so it "wraps" the function. It
checks the inputs on each entry to the function and the outputs on
each exit. If the input or output contracts are themselves
higher-order, those values are similarly "wrapped".
The or/c function itself is not a higher-order contract because it is
not a contract -- you can't wrap substring with or/c. However, you
could wrap it with:
(or/c (string? integer? . -> . string?) (string? integer? integer? .
-> . string?))
...which describes the function's optional third argument by combining
two higher-order contracts (one for two arguments and one for three)
into a single higher-order contract that accepts either kind of
application.
--Carl