[racket] Code that double checks is good, bad, other?

From: Matthias Felleisen (matthias at ccs.neu.edu)
Date: Sat Oct 4 15:04:53 EDT 2014

Here is an answer that's not a book but it should be one. 

1. If you write an exported function that looks like this: 

(define (workhorse x)
  (validate
    validate
     validate
      validate x ...)
  (compute with x ...))

I recommend that you factor out the validation into a contract: 

(provide 
  (contract-out 
   (->i ([x (lambda (x) 
                  (validate
	            validate
	             validate
	               validate x ...))])
           ...)

(define (workhorse x)
  (compute with x ...)

It is extremely likely that whoever uses workhorse needs to know about these checks, because they are a part of the interface. Put them there, and only there. 

2. If you are working on a chain of module and except for the top and bottom one, none has contact with the external world, validate values that flow thru the chain once: on the way in or out. Skip checks everywhere else. 

3. For the top and bottom value, write the contracts that you want (for the supplier) and weaken the contract that you promise (the client) and in between trust yourself. 

4. If you have a type system, use it instead of 3. As Neil says, you get some of these checks for free (during compile time) so do them. 

-- Matthias

  





Posted on the users mailing list.