<div dir="ltr"><div>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.</div><div><br></div>Matthias,<div><br></div><div>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.</div><div><br></div><div>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.</div><div><br></div><div>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.</div><div><br></div><div><br></div></div><div class="gmail_extra"><br><div class="gmail_quote">On Thu, Oct 2, 2014 at 9:20 AM, 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>
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>
<span class="">  (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>
</span>  (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>
<div><div class="h5"><br>
<br>
<br>
<br>
On Oct 1, 2014, at 10:46 PM, Alexander McLin <<a href="mailto:alex.mclin@gmail.com">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>
</div></div>> ____________________<br>
>  Racket Users list:<br>
>  <a href="http://lists.racket-lang.org/users" target="_blank">http://lists.racket-lang.org/users</a><br>
<br>
</blockquote></div><br></div>