[racket] Code that double checks is good, bad, other?
There's a simple rule in the world of contract engineering:
* as a client, demand the strongest possible promise from the serving module
* as a server, promise as little as you can get away with
-- Matthias
On Oct 4, 2014, at 3:42 PM, Sean Kanaley wrote:
> What do you mean by "weaken" in #3? I presume you mean use a more general type. Is this to allow for flexibility in future iterations? Promising any/c instead of void? ?
>
> On Sat, Oct 4, 2014 at 3:04 PM, Matthias Felleisen <matthias at ccs.neu.edu> wrote:
>
> 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
>
>
>
>
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.racket-lang.org/users/archive/attachments/20141004/216319b5/attachment.html>