<div dir="ltr"><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex"><span style="font-size:12.8000001907349px">From the error message, I changed the lambda to return (void) and then it worked.</span><br style="font-size:12.8000001907349px"><span style="font-size:12.8000001907349px">I think maybe the contract is wrong but frankly I don't understand much about contracts.</span></blockquote><div><br></div><div>The contract, by definition, is always right ;)</div><div><br></div><div>In this case, `response/output` takes as its first argument a procedure that accepts an output-port and returns void. [1] In contract-speak this is commonly written with dot notation as:</div><div><br></div><div>(output-port? . -> . void?) </div><div><br></div><div>but it appears in error messages, like the one above, with the equivalent notation:</div><div><br></div><div>(-> output-port? void?)<br></div><div><br></div><div><div>Note also that the error says the contract violation was "in the range of the 1st argument of" ... [giant contract follows]. That helps track down the error. The contract for the first argument is '(-> output-port? void?)'. This is a procedure contract. And "the range of" a procedure contract means the contract on the return value. Which in this case is `void?`. So the complaint is that the procedure given in the first argument is returning '11' when it should be returning void.</div></div><div><br></div><div>Why is (-> output-port? void?) the contract for the first arg of `response/output`? The idea is that you write to the output-port directly rather than returning a value to the caller. Insisting on void as a return value imposes an extra measure of discipline, and sets an expectation.</div><div><br></div><div>The reason your 'not-working' dispatcher is not working is that `write-bytes` does two things: it sends bytes to the output port, but then also returns the number of bytes written. [2] So this procedure:</div><div><br></div><div><span style="font-size:12.8000001907349px">(λ (op) (write-bytes #"Hello world" op))</span><br></div><div><span style="font-size:12.8000001907349px"><br></span></div><div><span style="font-size:12.8000001907349px">is defective because it returns the number of bytes. Meaning, it breaks the contract, which demands void. (That's also why your error is '11': that's the number of bytes in "Hello world"). </span></div><div><span style="font-size:12.8000001907349px"><br></span></div><div><span style="font-size:12.8000001907349px">But your revised procedure:</span></div><div><span style="font-size:12.8000001907349px"><br></span></div><div><span style="font-size:12.8000001907349px">(λ (op) (write-bytes #"Hello world" op) (void))</span><span style="font-size:12.8000001907349px"><br></span></div><div><span style="font-size:12.8000001907349px"><br></span></div><div><span style="font-size:12.8000001907349px">Meets the contract because it ignores the return value from `write-bytes` and returns (void) instead.</span></div><div><br></div><div>You should repeat this technique whenever you use `response/output`.</div><div><br></div><div>You can also look into `response/full` and `response/xexpr`, which can be a more convenient way of making simple HTML or text responses.</div><div><br></div><div><span style="font-size:12.8000001907349px"><br></span></div><div><br></div><div>[1] <a href="http://docs.racket-lang.org/web-server/http.html?q=response%2Foutput#%28def._%28%28lib._web-server%2Fhttp%2Fresponse-structs..rkt%29._response%2Foutput%29%29">http://docs.racket-lang.org/web-server/http.html?q=response%2Foutput#%28def._%28%28lib._web-server%2Fhttp%2Fresponse-structs..rkt%29._response%2Foutput%29%29</a></div><div><br></div><div>which cross-references</div><div><br></div><div><a href="http://docs.racket-lang.org/web-server/http.html?q=response%2Foutput#%28def._%28%28lib._web-server%2Fhttp%2Fresponse-structs..rkt%29._response%29%29">http://docs.racket-lang.org/web-server/http.html?q=response%2Foutput#%28def._%28%28lib._web-server%2Fhttp%2Fresponse-structs..rkt%29._response%29%29</a><br></div><div><br></div><div>[2] <a href="http://docs.racket-lang.org/reference/Byte_and_String_Output.html?q=write-bytes#%28def._%28%28quote._~23~25kernel%29._write-bytes%29%29">http://docs.racket-lang.org/reference/Byte_and_String_Output.html?q=write-bytes#%28def._%28%28quote._~23~25kernel%29._write-bytes%29%29</a></div><div><br></div><div>which cross-references</div><div><br></div><div><a href="http://docs.racket-lang.org/reference/Byte_and_String_Output.html?q=write-bytes#%28def._%28%28quote._~23~25kernel%29._write-string%29%29">http://docs.racket-lang.org/reference/Byte_and_String_Output.html?q=write-bytes#%28def._%28%28quote._~23~25kernel%29._write-string%29%29</a><br></div><div><br></div><div><br></div><div class="gmail_extra"><br><div class="gmail_quote">On Fri, Mar 6, 2015 at 3:48 PM, André Matheus <span dir="ltr"><<a href="mailto:amatheus@mac.com" target="_blank">amatheus@mac.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex"><div><div>Hi, starting a project of mine, I've setup a dispatch rule and a function to return the response.<br>To make things simple, I've used response/output, with a lambda writing to the output-port.<br>However, I've got the error:<br><br><span style="font-size:12px">response/output: contract violation</span><br><span style="font-size:12px">  expected: void?</span><br><span style="font-size:12px">  given: 11</span><br><span style="font-size:12px">  in: the range of</span><br><span style="font-size:12px">      the 1st argument of</span><br><span style="font-size:12px">      (->*</span><br><span style="font-size:12px">       ((-> output-port? void?))</span><br><span style="font-size:12px">       (#:code</span><br><span style="font-size:12px">        number?</span><br><span style="font-size:12px">        #:headers</span><br><span style="font-size:12px">        (listof header?)</span><br><span style="font-size:12px">        #:message</span><br><span style="font-size:12px">        bytes?</span><br><span style="font-size:12px">        #:mime-type</span><br><span style="font-size:12px">        (or/c bytes? #f)</span><br><span style="font-size:12px">        #:seconds</span><br><span style="font-size:12px">        number?)</span><br><span style="font-size:12px">       response?)</span><br><span style="font-size:12px">  contract from: </span><br><span style="font-size:12px">      <pkgs>/web-server-lib/web-server/http/response-structs.rkt</span><br><span style="font-size:12px">  blaming: /home/amatheus/Dropbox/focus/todagendas/teste.rkt</span><br><span style="font-size:12px">   (assuming the contract is correct)</span><br><span style="font-size:12px">  at: <pkgs>/web-server-lib/web-server/http/response-structs.rkt:41.2</span><br><span style="font-size:12px">  context...:</span><br><span style="font-size:12px">   /usr/share/racket/collects/racket/contract/private/blame.rkt:143:0: raise-blame-error16</span><br><span style="font-size:12px">   /usr/share/racket/pkgs/web-server-lib/web-server/http/response.rkt:115:12</span><br><br>So I've tried to use a response, with the same lambda, and it worked.<br>From the error message, I changed the lambda to return (void) and then it worked.<br><br>I think maybe the contract is wrong but frankly I don't understand much about contracts.<br><br>I've setup some code that exposes the problem. Navigating to "/working" and "/fixed" works<br>fine; navigating to "/not-working" exposes the problem.<br><br>#lang racket<br>(require web-server/dispatch<br>         web-server/servlet-env<br>         net/url<br>         web-server/http/request-structs<br>         web-server/http/response-structs)<br><br>(define (not-working req)<br>  (response/output (λ (op) (write-bytes #"Hello world" op))))<br><br>(define (working req)<br>  (response<br>   301 #"OK"<br>   (current-seconds) TEXT/HTML-MIME-TYPE<br>   empty<br>   (λ (op) (write-bytes #"Hello world" op))))<br><br>(define (fixed req)<br>  (response/output (λ (op) (write-bytes #"Hello world" op) (void))))<br><br>(define (url->request u)<br>    (make-request #"GET" (string->url u) empty<br>                  (delay empty) #f "1.2.3.4" 80 "4.3.2.1"))<br><br>(define-values (agenda-dispatch agenda-url)<br>  (dispatch-rules<br>   [("working") working]<br>   [("not-working")  not-working]<br>   [("fixed") fixed]))<br><br>(define (main)<br>  (serve/servlet agenda-dispatch<br>                 #:servlet-regexp #rx""<br>                 #:servlet-path ""))<br><br>(module+ main<br>  (main))<br><br>The contracts in response-structs.rkt:<br><br>(provide/contract<br> [struct response<br>         ([code number?]<br>          [message bytes?]<br>          [seconds number?]<br>          [mime (or/c false/c bytes?)]<br>          [headers (listof header?)]<br>          [output (output-port? . -> . void)])]<br> [response/full (-> number? bytes? number? (or/c false/c bytes?) (listof header?) (listof bytes?) response?)]<br> [response/output (->* ((-> output-port? void?))<br>                       (#:code number?<br>                        #:message bytes?<br>                        #:seconds number?<br>                        #:mime-type (or/c bytes? #f)<br>                        #:headers (listof header?))<br>                       response?)]<br> [TEXT/HTML-MIME-TYPE bytes?])<br><br>Is the contract wrong or am I doing something weird?<br><br>Thanks,<br><br>André<br></div></div><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></blockquote></div><br></div></div>