Liking cljdoc? Tell your friends :D

contract

As you saw in the description of defconstrainedfn core.contracts 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 core.contracts's [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]

Can you improve this documentation?Edit on GitHub

cljdoc is a website building & hosting documentation for Clojure/Script libraries

× close