On 10/08/2011 10:12 AM, Matthias Felleisen wrote:
[...]

(2) I object to

  provide-with-whatever-contract-you-already-have

because I think programmers should explicitly state what
they want (if they want something logical).

We can already do this

  (define primes-to-primes (->  (listof prime?) (listof prime?)))

  (provide/contract
    [f primes-to-primes]
    [primes-to-primes contract?])

So in some client module we can write

  (provide/contract
    [f primes-to-primes])

again.

I don't understand the benefit to your approach. I'd like to write something like the following this:

  (provide (re-contract-out f))

I believe your objection is that the contract for f is not manifest in this module: we have to chase down the source of f to find its contract. Perhaps you would say that re-contract-out is bad the way type inference for top-level functions is bad, and explicit contracts are better the way that explicit type declarations are better.

But in your alternative,

  (provide (contract-out [f contract-of-f]))

the contract of f is *still* not manifest in the module. Instead of chasing down f, we have to chase down contract-of-f. We've also duplicated code/knowledge (the association between f and contract-of-f) with all the problems that entails. Also, we've cluttered up the namespace with these contract-of-* bindings.

Of course, duplicating the contract expression would make it manifest, but it would aggravate the ill effects from code duplication. My experience: partly because of its lazy-require tricks, the db library has some duplication of contracts, and I hate it. I've also eliminated internal contracts to avoid having to repeat them in the externally-visible modules.

Ryan
_________________________________________________
 For list-related administrative tasks:
 http://lists.racket-lang.org/listinfo/users

Reply via email to