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