Contracts are the signatures of functions that we have been using. The vocabulary word changes to make it sound more legal. Contracts are actually enforced by Racket.
If you want to make sure a function takes in a number and puts out a number, you can include a contract when you define it. Here is a simple complete example of a function to add five to a number.
(require picturing-programs)
(require racket/contract)
; add-five: number -> number
(define/contract (add-five n)
(-> number? number?)
(+ 5 n))
(add-five "whoops")
Demo files: no contract, simple contract.
You can use any of the familiar type-testing functions that end in a question mark. Here is an incomplete list:
number?
string?
image?
any/c
: The /c
stands for contract
. Why any by itself is not correct is beyond what we will study.You can write contracts for functions with more than one argument.
The last argument of ->
is the type of the output.
Usually we put the inputs on one line and the outputs on another.
; add-num-length: number string -> number
; add the number and the length of the string
(define/contract (add-num-length n s)
(-> number? string?
number?)
(+ n (string-length s)))
(add-num-length 10 "whoops") ; OK => 16
(add-num-length "whoops" 10) ; ERROR signalled here