the relationship between a class and its clients as a formal agreement, expressing each party's rights and obligations
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.