On Sat, Jan 15, 2011 at 7:21 AM, Carl Eastlund <[email protected]> wrote: > On Sat, Jan 15, 2011 at 6:53 AM, Robby Findler > <[email protected]> wrote: >> On Fri, Jan 14, 2011 at 9:13 PM, Carl Eastlund <[email protected]> wrote: >>>> I think that most of the time that you re-provide something you really >>>> wanted to put the same contract on it, so it seems like we should make >>>> that easy. >>> >>> On the other hand, that means the number of requires and provides can >>> seriously impact a program's performance if a function has a >>> computationally intensive contract. I don't think we really want to >>> put hidden "gotchas" into the module system. >> >> The contract system should be able to be smart enough to avoid putting >> the redundant contracts on. After all, they are eq? to each other >> (altho I agree some care will have to be taken to make sure this >> happens). > > I don't think that's possible in general. For instance, the listof > contract has to traverse the entire list, recursively applying the > element contract to each part. There's no way to avoid rewrapping > there. Granted, providing a list of functions is not common, but any > contract can be implemented that way. The whole contract need not be > preserved after the projection has been applied. Our contract system > is too flexible to make hard guarantees about the effects of applying > the same contract twice.
If the contract is a first-order contract then we cannot do it (altho a listof functions will only check the listof part twice), yes. But I think we can deal with this problem if we decide to go this route. >>> Also, I occasionally make use of the fact that re-provides are >>> considered "the same binding" by the module system. So if A exports >>> X, and B re-exports that X, C can require both A and B. The duplicate >>> import of X doesn't cause an error because it's the same X. Changing >>> module exports is a little bit easier because of this -- for instance, >>> more than once I have used this property to keep (planet cce/scheme) >>> compatible with changes to the core that added overlapping bindings. >>> Adding a new contract means you suddenly have a different binding, >>> which can be less convenient. >> >> Wait a sec: I don't see how 'the same binding' can be on the table for >> one option and not the other? It seems like 'the same binding' in the >> current world can do two different things (specifically either include >> the 'via' message or not when there is an error). >> >> I tried this out with racket/load and the bindings were the same, but >> there was no via message. Maybe that is just part of the bug we're >> dealing with, tho? > > I'm not talking about "via" messages in contract errors. I'm talking > about syntax errors. The following program compiles and runs: > > #lang racket/load > (module A racket (define x 5) (provide x)) > (module B racket (require 'A) (provide x)) > (module C racket (require 'A) (require 'B)) > > But this program does not: > > #lang racket/load > (module A racket (define x 5) (provide/contract [x any/c])) > (module B racket (require 'A) (provide/contract [x any/c])) > (module C racket (require 'A) (require 'B)) > > The resulting error message: > > module: identifier already imported from a different source in: > x > (quote B) > (quote A) Oh I wasn't thinking carefully. Sorry about that. Robby _________________________________________________ For list-related administrative tasks: http://lists.racket-lang.org/listinfo/dev

