On May 18, 2012, at 6:24 PM, Neil Van Dyke wrote:

> Any new thoughts on adding a feature for disabling contracts?
> 
> In the past, I have been concerned about introducing contracts into large 
> performance-sensitive apps, since I didn't know the performance impact.  I 
> couldn't measure the performance impact without a large amount of work that 
> might have to then be thrown away.  The solution was to simply not try using 
> contracts.
> 
> I am newly interested in disabling contracts because my new code 
> documentation tool encourages the use of contracts, as well as developing 
> your modules as PLaneT packages.  However, as I am converting all my PLaneT 
> packages to use contracts, I fear this will make the packages less useful to 
> people who don't want the contract overhead.
> 
> Or, if no one is persuaded that this might be a good thing, perhaps there's a 
> submodules angle that makes implementing disable-able contracts interesting 
> to someone?  If so, it might also be relevant to Typed Racket.


When it comes to the cost of contracts you need to distinguish two different 
costs: 

 1. the cost of writing (provide/contract [f any/c]). This cost tends to be 
very very very low.  

 2. the cost of executing the programmer's contract. This cost is entirely 
controlled by the programmer. 

I know that point 2 doesn't say anything generally applicable. But that's all 
we can say. You can test very shallow properties at a module boundary. You can 
check complete correctness for flat properties. You can partially check 
higher-order properties for all uses in a program or you can sample them 
randomly (we're working on this one right now) once and for all. In the end it 
is you who chooses how much to check and how much your software component must 
be protected and how much it must promise to others on your team. 

;; ---- 

As for measuring and/or disabling contracts, you can always export all 
functionality twice, via submodules now. See code below. I am sure one could 
create macros that abstract over what you want imported. 

#lang racket ;; client.rkt

; (require (submod "server.rkt" export/c))
;; > (test 3)
;; cpu time: 552 real time: 558 gc time: 28
;; cpu time: 534 real time: 538 gc time: 27
;; cpu time: 533 real time: 537 gc time: 27
;; cpu time: 536 real time: 538 gc time: 26
;; cpu time: 543 real time: 548 gc time: 26

(require (submod "server.rkt" export))
;; > (test 3)
;; cpu time: 243 real time: 243 gc time: 0
;; cpu time: 230 real time: 230 gc time: 0
;; cpu time: 238 real time: 239 gc time: 0
;; cpu time: 233 real time: 234 gc time: 0
;; cpu time: 231 real time: 232 gc time: 0

(define (test N)
  (collect-garbage) (collect-garbage) (collect-garbage)
  (define l (build-list 10000 add1))
  (define s 
    (time
     (with-output-to-string
      (lambda ()
        (for ((i N))
          (show sqr l))))))
  (string-length s))
    

#lang racket ;; server.rkt 

(module+ export
         (provide show))

(module+ export/c
         (provide/contract
          [show (->i ([f (->i ((x integer?)) (y (x) (and/c integer? (>=/c 
x))))] [l list?]) [result (l) (and/c integer? (>=/c (apply + l)))])]))

(define (show f l)
  (for/fold ([sum 0]) ((x l))
    (define term (f x))
    (displayln `(,x ,term))
    (+ sum term)))




____________________
  Racket Users list:
  http://lists.racket-lang.org/users

Reply via email to