You're right in that the error should be shown in context. We'll think about it, and thanks for bring it up -- Matthias
On Oct 3, 2014, at 11:00 PM, Alexander McLin wrote: > Making a correction here, my wish error message should say this. > > in: the 1st argument of > (->* > ((and/c number? (between/c 0 1))) > (#:clamp-range boolean?) > number?) > > Because I understand that the phrase "the range of" means the last item in > the -> form which is the ->* contract. > > On Fri, Oct 3, 2014 at 10:55 PM, Alexander McLin <alex.mc...@gmail.com> wrote: > Actually I wasn't quite ready to move on. > > When I apply (curve 3) where (define curve (cubic-bezier a b) a and b are > bezier-control-point? > > I get the following contract error: > > --------------------------------------------------------------------------- > (curve 3) > . . cubic-bezier: contract violation > expected: (and/c number? (between/c 0 1)) > given: 3 > which isn't: (between/c 0 1) > in: the 1st argument of > the range of > (-> > bezier-control-point? > bezier-control-point? > (->* > ((and/c number? (between/c 0 1))) > (#:clamp-range boolean?) > number?)) > contract from: > /home/alexander/Workspace/Racket/cubic-bezier.rkt > blaming: /home/alexander/Workspace/Racket/experimental.rkt > at: /home/alexander/Workspace/Racket/cubic-bezier.rkt:8.11 > > ---------------------------------------------------------------------------- > > Is there a way I can fine-tune the error message so instead of saying > > in: the 1st argument of > the range of > (-> > bezier-control-point? > bezier-control-point? > (->* > ((and/c number? (between/c 0 1))) > (#:clamp-range boolean?) > number?)) > > It says > > in: the 1st argument of > the range of > (->* > ((and/c number? (between/c 0 1))) > (#:clamp-range boolean?) > number?) > > The above contract is really what is coming into play here when using curve, > the surrounding -> form is a distraction and I stare at it for a few moments > mentally parsing to find the right part that is being violated. The -> > contract is only relevant to cubic-bezier and I think confusing because the > lambda that is returned from cubic-bezier may be called after some time has > passed and — at least for me — cubic-bezier is long since gone, and thus out > of mind. > > Alexander McLin > > > > On Fri, Oct 3, 2014 at 9:59 PM, Alexander McLin <alex.mc...@gmail.com> wrote: > Good evening Mathias, > > After studying your program and mine, and running various permutations, I > understand where I was going wrong. It appears that while doing manual > experimentation I had gotten confused to which module I was actually in the > REPL when calling various functions by hand. Also my test cases weren't fine > grained enough to detect each unique contract violation generated by suitable > bad inputs. > > Thanks Mathias! Your examples have helped to sharpen my understanding of how > contract boundaries work. > > Alex > > On Thu, Oct 2, 2014 at 2:36 PM, Matthias Felleisen <matth...@ccs.neu.edu> > wrote: > > 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