# clojure/core.contracts

Adding contract from old trammel version

fogus committed Jan 22, 2013
Showing with 82 additions and 0 deletions.
1. +82 −0 docs/contract.org
 @@ -0,0 +1,82 @@ +--- +title: Trammel - Isolated Unnamed Contracts +--- + +As you saw in the description of [`defconstrainedfn`](../defconstrainedfn/) Trammel allows you to create functions with a localized and dependent contract. However, there may be circumstances where the separation of contract and constrained function is preferred. Take for example, a simple `slope` function: + +
+
+
+
+
(defn sqr [n] (* n n))
+
+
+
+
+ +Defining a separate contract for this function is a simple matter: + +
+
+
+
+
(def sqr-contract
(contract sqr-constraints
"Defines the constraints for squaring"
[n] [number? (not= 0 n) => pos? number?]))
+
+
+
+
+ +We can then define a constrained version of `sqr` using Trammel's [`with-constraints`](../with-constraints/) macro: + +
+
+
+
+
(def constrained-sqr
(with-constraints
sqr
sqr-contract))

(constrained-sqr 5)
;=> 25

(constrained-sqr -5)
;=> 25

(constrained-sqr 0)
; java.lang.AssertionError: Assert failed:
(not= 0 num)

(constrained-sqr :a)
; java.lang.AssertionError: Assert failed:
(number? num)
+
+
+
+
+ +However, this constraint definition for `sqr`, while accurate, is very broad. In fact, the software team developing software for the 8-bit Atari console would not be able to use `constrained-sqr` as it is far too liberal. Therefore, they can define their own contract that further constrains `constrained-sqr`: + +
+
+
+
+
(def sqr-8bit-contract
(contract atari-constraints
"Defines the constraints for Atari 2600 sqr"
[_] [number? => (< % 256)]))

(def sqr-8bit
(with-constraints
constrained-sqr
sqr-8bit-contract))

(sqr-8bit 5)
;=> 25

(sqr-8bit 0)
; java.lang.AssertionError:
; Assert failed: (not= 0 num)
+
+
+
+
+ +And all appears to be in order -- except: + +
+
+
+
+
(sqr-8bit 100)
; java.lang.AssertionError:
; Assert failed: (< % 256)
+
+
+
+
+ +That is, calling the function `sqr-8bit` with `100` causes a *post-condition* failure! The reason for this is because the underlying `sqr` is the same old arbitrary-precision version when what we really want is a function that deals in only 8-bit values. There are two possible ways to do this: + +1. Create a version of `sqr-8bit` that does in fact deal in 8-bit values +2. Tighten the constraint on `constrained-sqr` further by applying another contract + +
+
+
+
+
(def sqr-8bit-contract
(contract atari-constraints
"Defines the constraints for Atari 2600 sqr"
[n] [(< n 16) integer? pos? => (< % 256)]))

(def sqr-8bit
(with-constraints
constrained-sqr
sqr-8bit-contract))

(sqr-8bit 15)
;=> 225

(sqr-8bit -5)
; java.lang.AssertionError:
; Assert failed: (pos? n)

(sqr-8bit 15.9687194)
; java.lang.AssertionError:
; Assert failed: (integer? n)

(sqr-8bit 16)
; java.lang.AssertionError:
; Assert failed: (< n 16)
+
+
+
+
+ +Using `contract` and `with-constraints` you were able to tighten the constraints on both the pre- and post-conditions of the `sqr` function. However, what if you wanted to relax the requirements? Stay tuned. + +[return to documentation](../docs.html)