Trammel

a contracts-programming library for Clojure

Contracts Programming

the relationship between a class and its clients as a formal agreement, expressing each party's rights and obligations

read more

While defining contracts local to the constrained function is nice (see defconstrainedfn for more information), very often you will find yourself in possession of an existing function that is not constrained:

(sqr 0)
;=> 0

In this case, Trammel provides the provide-contracts macro to define contracts and apply them dynamically to existing functions:

(provide-contracts
  [sqr "Constraints for squaring"
    [x] [number? (not= 0 x) => number? pos?]])

(sqr 0)
; java.lang.AssertionError:
; Assert failed: (not= 0 n)

As shown, the sqr function is dynamically modified with the contract defined in the body of provide-contracts. This macro can take any number of vectors where each corresponds to a contract for a given function; including multiple arities embedded within. Trammel also allows you to include existing named contracts (see defcontract for more information) instead of the contract specification vector, as shown below:

(defcontract sqr-contract
  "Defines the constraints on squaring."
  [n] [number? (not= 0 n) => pos? number?])

(sqr 0)
;=> 0

(provide-contracts
  [sqr "Apply the contract for squaring"
       sqr-contract])

(sqr 0)
; java.lang.AssertionError:
; Assert failed: (not= 0 n)

provide-contracts gives you a lot of flexibilty in how to separate functions from their contracts and likewise apply them in domain-specific ways.

return to documentation

clojars → source code → tickets → wiki →