<html><head></head><body style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space; "><div><br></div><div>You're right in that the error should be shown in context. We'll think about it, and thanks for bring it up -- Matthias</div><div><br></div><div><br></div><br><div><div>On Oct 3, 2014, at 11:00 PM, Alexander McLin wrote:</div><br class="Apple-interchange-newline"><blockquote type="cite"><div dir="ltr">Making a correction here, my wish error message should say this.<div><br></div><div><div style="font-family:arial,sans-serif;font-size:13px"><b> in: the 1st argument of</b></div><span class="im" style="font-family:arial,sans-serif;font-size:13px"><div><b>       (->*</b></div><div><b>        ((and/c number? (between/c 0 1)))</b></div><div><b>        (#:clamp-range boolean?)</b></div><div><b>        number?)</b></div><div><b><br></b></div><div><font color="#000000">Because I understand that the phrase <b>"the range of"</b> means the last item in the -> form which is the ->* contract.</font></div></span></div></div><div class="gmail_extra"><br><div class="gmail_quote">On Fri, Oct 3, 2014 at 10:55 PM, Alexander McLin <span dir="ltr"><<a href="mailto:alex.mclin@gmail.com" target="_blank">alex.mclin@gmail.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr">Actually I wasn't quite ready to move on.<div><br></div><div>When I apply (curve 3) where (define curve (cubic-bezier a b) a and b are bezier-control-point?</div><div><br></div><div>I get the following contract error:</div><div><br></div><div>---------------------------------------------------------------------------</div><div><div><b>(curve 3)</b></div><div><b>. . cubic-bezier: contract violation</b></div><div><b>  expected: (and/c number? (between/c 0 1))</b></div><div><b>  given: 3</b></div><div><b>  which isn't: (between/c 0 1)</b></div><div><b>  in: the 1st argument of</b></div><div><b>      the range of</b></div><span class=""><div><b>      (-></b></div><div><b>       bezier-control-point?</b></div><div><b>       bezier-control-point?</b></div><div><b>       (->*</b></div><div><b>        ((and/c number? (between/c 0 1)))</b></div><div><b>        (#:clamp-range boolean?)</b></div><div><b>        number?))</b></div></span><div><b>  contract from: </b></div><div><b>      /home/alexander/Workspace/Racket/cubic-bezier.rkt</b></div><div><b>  blaming: /home/alexander/Workspace/Racket/experimental.rkt</b></div><div><b>  at: /home/alexander/Workspace/Racket/cubic-bezier.rkt:8.11</b></div></div><div><b><br></b></div><div>----------------------------------------------------------------------------</div><div><br></div><div>Is there a way I can fine-tune the error message so instead of saying</div><div><br></div><div><div><b> in: the 1st argument of</b></div><div><b>      the range of</b></div><span class=""><div><b>      (-></b></div><div><b>       bezier-control-point?</b></div><div><b>       bezier-control-point?</b></div><div><b>       (->*</b></div><div><b>        ((and/c number? (between/c 0 1)))</b></div><div><b>        (#:clamp-range boolean?)</b></div><div><b>        number?))</b></div></span></div><div><b><br></b></div><div>It says</div><div><br></div><div><div><b> in: the 1st argument of</b></div><div><b>      the range of</b></div><span class=""><div><b>       (->*</b></div><div><b>        ((and/c number? (between/c 0 1)))</b></div><div><b>        (#:clamp-range boolean?)</b></div><div><b>        number?)</b></div></span></div><div><b><br></b></div><div>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.</div><span class="HOEnZb"><font color="#888888"><div><br></div><div>Alexander McLin</div><div><br></div><div><br></div></font></span></div><div class="HOEnZb"><div class="h5"><div class="gmail_extra"><br><div class="gmail_quote">On Fri, Oct 3, 2014 at 9:59 PM, Alexander McLin <span dir="ltr"><<a href="mailto:alex.mclin@gmail.com" target="_blank">alex.mclin@gmail.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr">Good evening Mathias,<div><br></div><div>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.</div><div><br></div><div>Thanks Mathias! Your examples have helped to sharpen my understanding of how contract boundaries work.</div><div><br></div><div>Alex</div></div><div><div><div class="gmail_extra"><br><div class="gmail_quote">On Thu, Oct 2, 2014 at 2:36 PM, Matthias Felleisen <span dir="ltr"><<a href="mailto:matthias@ccs.neu.edu" target="_blank">matthias@ccs.neu.edu</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><br>
If you use this as the program:<br>
<span><br>
#lang racket<br>
<br>
;; contracts set up boundaries between two regions of a program, say two modules<br>
<br>
;; ---------------------------------------------------------------------------------------------------<br>
;; the library<br>
</span><span>(provide (contract-out<br>
           [struct bezier-control-point ((x (and/c number? (between/c 0 1))) (y number?))]<br>
           [cubic-bezier (-> bezier-control-point?<br>
                             bezier-control-point?<br>
                             (->* ((and/c number? (between/c 0 1)))<br>
                                  (#:clamp-range boolean?)<br>
                                  number?))]))<br>
<br>
(struct bezier-control-point (x y) #:transparent)<br>
<br>
(define (cubic-bezier a b)<br>
  ;; now produce a curve via Bezier triangulation<br>
  (lambda (x #:clamp-range [cr #f])<br>
    x))<br>
<br>
</span><span>;; ---------------------------------------------------------------------------------------------------<br>
;; the module that uses it<br>
</span>(module+ test<br>
 (require (submod ".."))<br>
<span><br>
 (define a (bezier-control-point 0.1 5.0))<br>
 (define b (bezier-control-point 0.3 9.0))<br>
<br>
 ((cubic-bezier a b)<br>
  ;; a contract violation because i isn't comparable<br>
  (sqrt -1)))<br>
<br>
<br>
</span>drracket or raco test file.rkt will show contract errors.<br>
<div><div><br>
<br>
<br>
<br>
On Oct 2, 2014, at 1:50 PM, Alexander McLin <<a href="mailto:alex.mclin@gmail.com" target="_blank">alex.mclin@gmail.com</a>> wrote:<br>
<br>
> 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.<br>
><br>
> Matthias,<br>
><br>
> 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.<br>
><br>
> 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.<br>
><br>
> 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.<br>
><br>
><br>
><br>
> On Thu, Oct 2, 2014 at 9:20 AM, Matthias Felleisen <<a href="mailto:matthias@ccs.neu.edu" target="_blank">matthias@ccs.neu.edu</a>> wrote:<br>
><br>
> Let's make Spencer's question concrete. Say we have this situation:<br>
><br>
> #lang racket<br>
><br>
> ;; contracts set up boundaries between two regions of a program, say two modules<br>
><br>
> ;; ---------------------------------------------------------------------------------------------------<br>
> ;; the library<br>
> (module server racket<br>
>   (provide (contract-out<br>
>             [struct bezier-control-point ((x (and/c number? (between/c 0 1))) (y number?))]<br>
>             [cubic-bezier (-> bezier-control-point?<br>
>                               bezier-control-point?<br>
>                               (->* ((and/c number? (between/c 0 1)))<br>
>                                    (#:clamp-range boolean?)<br>
>                                    number?))]))<br>
><br>
>   (struct bezier-control-point (x y) #:transparent)<br>
><br>
>   (define (cubic-bezier a b)<br>
>     ;; now produce a curve via Bezier triangulation<br>
>     (lambda (x #:clamp-range [cr #f])<br>
>       x)))<br>
><br>
> ;; ---------------------------------------------------------------------------------------------------<br>
> ;; the module that uses it<br>
> (module client racket<br>
>   (require (submod ".." server))<br>
><br>
>   (define a (bezier-control-point 0.1 5.0))<br>
>   (define b (bezier-control-point 0.3 9.0))<br>
><br>
>   ((cubic-bezier a b)<br>
>    ;; a contract violation because i isn't comparable<br>
>    (sqrt -1)))<br>
><br>
> ;; ---------------------------------------------------------------------------------------------------<br>
> ;; run program run<br>
> (require 'client)<br>
><br>
> I assume you want to see other violations. Can you explain with this example w/o going into Bezier?<br>
> (I just know enough about Bezier to draw curves.)<br>
><br>
> -- Matthias<br>
><br>
><br>
><br>
><br>
> On Oct 1, 2014, at 10:46 PM, Alexander McLin <<a href="mailto:alex.mclin@gmail.com" target="_blank">alex.mclin@gmail.com</a>> wrote:<br>
><br>
> > Hello,<br>
> ><br>
> > 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.<br>
> ><br>
> > 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.<br>
> ><br>
> > 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.<br>
> ><br>
> > Here are the contracts I defined provisionally:<br>
> ><br>
> > (provide (contract-out<br>
> >           [struct bezier-control-point ((x (and/c number? (between/c 0 1)))<br>
> >                                                       (y number?))]<br>
> >           [cubic-bezier (-> bezier-control-point?<br>
> >                                      bezier-control-point?<br>
> >                                     (->* ((and/c number? (between/c 0 1)))<br>
> >                                            (#:clamp-range boolean?)<br>
> >                                            number?))]))<br>
> ><br>
> > 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.<br>
> ><br>
> > How can I attach a more complex contract to cubic-bezier's value?<br>
> ><br>
> > Thank you<br>
> > Alexander McLin<br>
> > ____________________<br>
> >  Racket Users list:<br>
> >  <a href="http://lists.racket-lang.org/users" target="_blank">http://lists.racket-lang.org/users</a><br>
><br>
><br>
<br>
</div></div></blockquote></div><br></div>
</div></div></blockquote></div><br></div>
</div></div></blockquote></div><br></div>
</blockquote></div><br></body></html>