I think that you will press at least one, and maybe both of them:
Using (provide (contract-out ....)) means that the contract is applied only at the module boundary - only for other modules for which require this. Therefore, if your test case was in the same module, the contract will not apply. Instead, you can use define/contract to make the contract applicable to the thing itself, both in the module where it is defined and externally if you provide it.
There is a special contract form for struct s in which you specify a contract for each field. What you tried above is a contract only for the constructor function. Although this may be what you want, consider a contract for struct instead.
Combining both actions, you can:
;; Define the contract on the struct itself. ;; Contract is used even within this module. (provide car) (define-struct/contract car ([model string?] [year integer?]))
If you want the contract to be applied only at the border of the module, you should use:
;; Define the contract only as `provide`d. ;; Contract is used only for code `require`-ing this module. (provide (contract-out (struct car ([model string?] [year integer?])))) (struct car (model year))
ps FWIW in Racket, the common style is not to use the structure name - car not car .
Refresh . To more clearly illustrate the difference:
#lang racket (module mod racket (provide car0) (define-struct/contract car0 ([model string?] [year integer?])) (car0 "foo" "bar") ;; gives contract violation ;; because contract on struct itself (struct car1 (model year)) (provide (contract-out (struct car1 ([model string?] [year integer?])))) (car1 "foo" "bar") ;; does NOT give contract violation ;; because contract only on the `provide` ) (require 'mod) (car0 "foo" "bar") ;; gives contract violation (car1 "foo" "bar") ;; gives contract violation
source share