<html><head><meta http-equiv="Content-Type" content="text/html charset=utf-8"><base></head><body style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;"><br><div><div>On Jun 29, 2014, at 8:44 PM, Roman Klochkov <<a href="mailto:kalimehtar@mail.ru">kalimehtar@mail.ru</a>> wrote:</div><br class="Apple-interchange-newline"><blockquote type="cite"><div style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;"><br>procedure-has-arity is not needed. I can write:<br>> (define/contract (test f) (-> (or/c<span class="Apple-converted-space"> </span><br> (-> input-port? any/c any)<br> (-> input-port? any/c any/c any)<br> (-> input-port? any/c any/c any/c any)<br> (->* (input-port? any/c) #:rest list? any)) any)<br> 1)<br>> (test (λ (x y) 2))<br>1<br><br></div></blockquote><div><br></div><div>procedure-has-arity is needed if f is something like (λ (x y . rst) x). </div><div><br></div><div>In this case or/c would report an error because f would match more than one of the contracts in the or/c. </div><div>That’s also why it needs to be procedure-has-arity, and not procedure-arity-includes. </div><br><blockquote type="cite"><div style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;">But I need any number of args, more than two. I can, of course write something like<br>(define-syntax (make-contract stx)<br> (syntax-case stx ()<br> [_ (with-syntax ([(CLAUSES ...) (for/list ([i 100]) ;;; hope 100 enough many<br> #`(-> input-port? any/c<span class="Apple-converted-space"> </span><br> #,@(for/list ([j i]) #'any/c)))])<br> #'(or/c CLAUSES ... (->* (input-port? any/c) #:rest list? any)))]))<br><br>But it is very slow and clumsy.<br><br></div></blockquote><div><br></div><div>In that case, you could use this:</div><div><a href="http://docs.racket-lang.org/reference/Building_New_Contract_Combinators.html">http://docs.racket-lang.org/reference/Building_New_Contract_Combinators.html</a></div><br><blockquote type="cite"><div style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;"><br>Sun, 29 Jun 2014 18:43:15 -0500 от Robby Findler <<a href="mailto:robby@eecs.northwestern.edu">robby@eecs.northwestern.edu</a>>:<br><blockquote style="margin: 10px; padding: 0px 0px 0px 10px; border-left-color: rgb(8, 87, 166); border-left-width: 1px; border-left-style: solid; position: static; z-index: auto;"><div class="js-helper js-readmsg-msg"><base href="https://e.mail.ru/" target="_self"><div id="style_14040854020000000783_BODY">Why isn't:<br><br> (->* (input-port? any/c) #:rest list? any)<br><br>by itself the contract that you want?<br><br>Robby<br><br><br>On Sun, Jun 29, 2014 at 12:08 PM, Alexander D. Knauth<br><<a href="x-msg://19/compose?To=alexander@knauth.org">alexander@knauth.org</a>> wrote:<br>> You can use or/c to do this, as long as you guard them like this so that no<br>> more than one contract matches at a time:<br>> (or/c<br>> (and/c (procedure-has-arity/c 2) (-> input-port? any/c any))<br>> (and/c (procedure-has-arity/c 3) (-> input-port? any/c any/c any))<br>> (and/c (procedure-has-arity/c 4) (-> input-port? any/c any/c any/c any))<br>> (->* (input-port? any/c) #:rest list? any)<br>> )<br>><br>> Or, you could use if/c from unstable/contract, or define a cond/c macro like<br>> this:<br>> (require unstable/contract)<br>> (define-syntax cond/c<br>> (syntax-rules (else)<br>> [(cond/c) none/c]<br>> [(cond/c [else else-c])<br>> else-c]<br>> [(cond/c [pred then-c] clause ...)<br>> (if/c pred<br>> then-c<br>> (cond/c clause ...))]))<br>><br>> (cond/c [(procedure-has-arity/c 2) (-> input-port? any/c any)]<br>> [(procedure-has-arity/c 3) (-> input-port? any/c any/c any)]<br>> [(procedure-has-arity/c 4) (-> input-port? any/c any/c any/c any)]<br>> [else (->* (input-port? any/c) #:rest list? any)])<br>><br>> By the way it has to be procedure-has-arity/c, not<br>> procedure-includes-arity/c:<br>> (define (procedure-has-arity/c arity)<br>> (define normalized-arity (normalize-arity arity))<br>> (flat-named-contract<br>> `(procedure-has-arity/c ,normalized-arity)<br>> (λ (f)<br>> (and (procedure? f)<br>> (arity=? (procedure-arity f) normalized-arity)))))<br>><br>> On Jun 29, 2014, at 8:00 AM, Roman Klochkov <<a href="x-msg://19/compose?To=kalimehtar@mail.ru">kalimehtar@mail.ru</a>> wrote:<br>><br>> How to make a contract, that accepts<br>> (-> input-port? any/c any)<br>> (-> input-port? any/c any/c any)<br>> (-> input-port? any/c any/c any/c any)<br>> ...<br>> and<br>> (->* (input-port? any/c) #:rest list? any)<br>><br>><br>> So theare should be at least two args and first arg should be input-port.<br>><br>> --<br>> Roman Klochkov<br>><br>> ____________________<br>> Racket Users list:<br>><span class="Apple-converted-space"> </span><a href="http://lists.racket-lang.org/users" target="_blank">http://lists.racket-lang.org/users</a><br>><br>><br>><br>> ____________________<br>> Racket Users list:<br>><span class="Apple-converted-space"> </span><a href="http://lists.racket-lang.org/users" target="_blank">http://lists.racket-lang.org/users</a><br>><br></div><base href="https://e.mail.ru/" target="_self"></div></blockquote><br><br>--<span class="Apple-converted-space"> </span><br>Roman Klochkov</div></blockquote></div><br></body></html>