If you use this as the program: #lang racket
;; contracts set up boundaries between two regions of a program, say two modules ;; --------------------------------------------------------------------------------------------------- ;; the library (provide (contract-out [struct bezier-control-point ((x (and/c number? (between/c 0 1))) (y number?))] [cubic-bezier (-> bezier-control-point? bezier-control-point? (->* ((and/c number? (between/c 0 1))) (#:clamp-range boolean?) number?))])) (struct bezier-control-point (x y) #:transparent) (define (cubic-bezier a b) ;; now produce a curve via Bezier triangulation (lambda (x #:clamp-range [cr #f]) x)) ;; --------------------------------------------------------------------------------------------------- ;; the module that uses it (module+ test (require (submod "..")) (define a (bezier-control-point 0.1 5.0)) (define b (bezier-control-point 0.3 9.0)) ((cubic-bezier a b) ;; a contract violation because i isn't comparable (sqrt -1))) drracket or raco test file.rkt will show contract errors. On Oct 2, 2014, at 1:50 PM, Alexander McLin <alex.mc...@gmail.com> wrote: > Spencer, I'm calling cubic-bezier from within a (module+ test (require submod > "..")...) form that itself is defined in the file where cubic-bezier is > defined. Also I tried from within REPL and requiring the code file. > > Matthias, > > I ran your example and it works exactly the way I wanted. The lambda returned > from cubic-bezier properly raises contract violations when bad inputs are > given for the required parameter and optional keyword. > > Examining the differences between your example and my original > implementation, my functions are directly defined in top level in the file, > after #lang racket, not wrapped within a module. And I'm running my test > cases within a (module+ test (require submod "..")) form. > > In my test cases within (module+ test...), violations are correctly reported > when I give bad inputs to cubic-bezier and bezier-control-point structs. > Except the lambda, no violations are reported with bad inputs. Is it because > I'm incorrectly using modules? I had thought that module+ and (require submod > "..") would allow the contract system to come into full force. > > > > On Thu, Oct 2, 2014 at 9:20 AM, Matthias Felleisen <matth...@ccs.neu.edu> > wrote: > > Let's make Spencer's question concrete. Say we have this situation: > > #lang racket > > ;; contracts set up boundaries between two regions of a program, say two > modules > > ;; > --------------------------------------------------------------------------------------------------- > ;; the library > (module server racket > (provide (contract-out > [struct bezier-control-point ((x (and/c number? (between/c 0 1))) > (y number?))] > [cubic-bezier (-> bezier-control-point? > bezier-control-point? > (->* ((and/c number? (between/c 0 1))) > (#:clamp-range boolean?) > number?))])) > > (struct bezier-control-point (x y) #:transparent) > > (define (cubic-bezier a b) > ;; now produce a curve via Bezier triangulation > (lambda (x #:clamp-range [cr #f]) > x))) > > ;; > --------------------------------------------------------------------------------------------------- > ;; the module that uses it > (module client racket > (require (submod ".." server)) > > (define a (bezier-control-point 0.1 5.0)) > (define b (bezier-control-point 0.3 9.0)) > > ((cubic-bezier a b) > ;; a contract violation because i isn't comparable > (sqrt -1))) > > ;; > --------------------------------------------------------------------------------------------------- > ;; run program run > (require 'client) > > I assume you want to see other violations. Can you explain with this example > w/o going into Bezier? > (I just know enough about Bezier to draw curves.) > > -- Matthias > > > > > On Oct 1, 2014, at 10:46 PM, Alexander McLin <alex.mc...@gmail.com> wrote: > > > Hello, > > > > I've been working on a sample project to better understand how to use the > > contract system. I created a simple Bezier curve implementation and am > > using (provide (contract-out...) to attach contracts to the provided > > bindings. > > > > Basically I have a procedure called cubic-bezier that accepts two control > > point structs used to define the curve. It returns another procedure that > > actually generates the curve, it accepts an integer parameter that lies on > > [0, 1] and an optional keyword #:clamp-range. The generator procedure > > returns a number. > > > > The control point structure is a simple posn type that accepts X and Y > > fields where X must be between 0 and 1, and Y is allowed to be any number. > > > > Here are the contracts I defined provisionally: > > > > (provide (contract-out > > [struct bezier-control-point ((x (and/c number? (between/c 0 1))) > > (y number?))] > > [cubic-bezier (-> bezier-control-point? > > bezier-control-point? > > (->* ((and/c number? (between/c 0 1))) > > (#:clamp-range boolean?) > > number?))])) > > > > For the contract attached to cubic-bezier using ->, my thinking was to use > > ->* to generate the contract for the procedure returned by cubic-bezier but > > it's not working, meaning I'm not getting the any contract violations I'm > > expecting when giving bad inputs to cubic-bezier's value. > > > > How can I attach a more complex contract to cubic-bezier's value? > > > > Thank you > > Alexander McLin > > ____________________ > > Racket Users list: > > http://lists.racket-lang.org/users > > ____________________ Racket Users list: http://lists.racket-lang.org/users