# Why are contracts not procedures?

**URL:** <https://racket.discourse.group/t/why-are-contracts-not-procedures/3727>\
**Category:** Questions & Answers\
**Tags:** question\
**Created:** [May 6, 2025, 7:51pm UTC](https://racket.discourse.group/t/why-are-contracts-not-procedures/3727 "2025-05-06T19:51:26Z")\
**Posts on this page:** 3\
**Page:** 1

<div class="post-metadata">

**Author:** ![joskoot](https://yyz2.discourse-cdn.com/free1/user_avatar/racket.discourse.group/joskoot/32/1964_2.png) [@joskoot](https://racket.discourse.group/u/joskoot)\
**Post date:** [May 6, 2025, 7:51pm UTC](https://racket.discourse.group/t/why-are-contracts-not-procedures/3727/1 "2025-05-06T19:51:26Z")

</div>

We have:

```scheme
(procedure? (-> any/c any/c)) ; -> #f
(contract? (-> any/c any/c)) ; -> #t
(contract? (λ (x) #t)) ; -> #t

```

Every procedure satisfying contract (-\> any/c any(c) is accepted as a contract, but the reverse is not true. Why not every contract is a procedure too? IIUC, contracts are checked only when crossing a module boundary. May be this is the reason. Would it be possible to make

```scheme
(-> any/c any/c)

```

satisfy predicate procedure? too or is the different behaviour within a module and between module crossings a strong argument not to do so?

---

<div class="post-metadata">

**Author:** ![LiberalArtist](https://yyz2.discourse-cdn.com/free1/user_avatar/racket.discourse.group/liberalartist/32/151_2.png) [@LiberalArtist](https://racket.discourse.group/u/LiberalArtist)\
**Post date:** [May 6, 2025, 8:43pm UTC](https://racket.discourse.group/t/why-are-contracts-not-procedures/3727/3 "2025-05-06T20:43:40Z")

</div>

There are several answers.

1. We also have:

2. Many contracts are actually higher-order—including seemingly simple ones, like `(-> any/c any/c)`. These contracts **cannot** give an immediate, definitive answer that some value satisfies the contract: they can say “no, definitely not” or “so far, but we need to keep watching”. Contract attachment forms return chaperones or general impersonators of the original values to detect violations that are not immediately visible.  
As a concrete example, consider:

3. To give good error messages, especially for higher-order contracts, contract-attachment forms use additional pieces of information, not just the value to be contracted. See the [`contract`](https://docs.racket-lang.org/reference/attaching-contracts-to-values.html#%28form._%28%28lib._racket%2Fcontract%2Fprivate%2Fbase..rkt%29._contract%29%29) form for some details. Since many of these pieces of information relate to the source location, macros make sense for attaching contracts to values.

4. Many contracts **do** satisfy `procedure?`! Specifically, “flat” (i.e. first-order) contracts can be used directly as procedures, except for automatic promotion. For example, you can write:

---

<div class="post-metadata">

**Author:** ![joskoot](https://yyz2.discourse-cdn.com/free1/user_avatar/racket.discourse.group/joskoot/32/1964_2.png) [@joskoot](https://racket.discourse.group/u/joskoot)\
**Post date:** [May 7, 2025, 7:13am UTC](https://racket.discourse.group/t/why-are-contracts-not-procedures/3727/4 "2025-05-07T07:13:14Z")

</div>

Thanks for the replies. Clarifies much.
