digitalmars.D - Feature request - isolated "in" contracts
- Arcane Jill (23/23) Aug 26 2004 I would very much like this to compile:
- Russ Lewis (9/35) Aug 26 2004 I agree, but I would further argue that isolated "out" contracts should
- Charlie (8/37) Aug 26 2004 I'm not sure what can be done about this, other than slap the developer.
- Arcane Jill (34/40) Aug 26 2004 It would have to be done by the compiler. Currently, given the code:
- Charlie (4/46) Aug 26 2004 Ahh yes, thanks for clarifying. Yes that looks like a good call, and li...
- Andy Friesen (47/75) Aug 26 2004 Very!
- Andy Friesen (9/15) Aug 26 2004 ... doh. This is all hogwash because testing against instance data is
- Sean Kelly (6/18) Aug 26 2004 But aren't classes also interfaces? And what about free functions (thou...
- Walter (28/50) Aug 26 2004 bug,
- Arcane Jill (29/47) Aug 27 2004 That is the situation /now/, yes. However, this was a feature request. I...
- Walter (15/32) Aug 27 2004 You don't need to expose the contract - the contract just has to be
- Arcane Jill (4/8) Aug 27 2004 I see only one version of phobos.lib in my download.
- Walter (6/13) Aug 27 2004 would
- Stewart Gordon (16/24) Aug 27 2004 I disagree. The end user isn't going to be calling OS API functions
- Walter (5/21) Aug 27 2004 Yes, they do. I call OS API functions all the time in my code.
- Stewart Gordon (13/20) Sep 01 2004 You mean when you're doing word processing, graphic design, browsing the...
- Russ Lewis (26/39) Aug 27 2004 What about the reasons I posted? Contracts are useful for optimization,...
- Walter (12/35) Aug 27 2004 That's true, contracts are possibly valuable hints for optimization.
- Andy Friesen (12/22) Aug 27 2004 Should they? It /is/ an A, after all. Shouldn't it be expected to
- Russ Lewis (14/30) Aug 28 2004 Right! It should be valid for the caller to assert A's preconditions,
- Norbert Nemec (37/52) Aug 30 2004 I strongly disagree.
I would very much like this to compile: Until yesterday, this compiled, but incorrectly. Walter has now fixed this bug, but he's fixed it in such a way that it now won't compile at all. The issue is this. A function's "in" contract is a precondition with which /callers/ are expected to comply. If they do not, the bug is in the callers' code, not in the function body. Now, if the function is in a commercial library, the creators of that library may wish to keep their source code to themselves - but they'd still want to expose the precondition. Worse, the callers' code could still be at the debug stage, while the library code may be a release build - in which case, not only will the application developer not be made aware of the precondition, but it won't even be executed! The resolution is that preconditions must always be executed by the caller, not the callee. That way, caller bugs caused by violating the contract will be found, as they should. And these means that it must be possible to expose an "in" contract without exposing the implementation. Does that sound reasonable? Arcane Jill
Aug 26 2004
Arcane Jill wrote:I would very much like this to compile: Until yesterday, this compiled, but incorrectly. Walter has now fixed this bug, but he's fixed it in such a way that it now won't compile at all. The issue is this. A function's "in" contract is a precondition with which /callers/ are expected to comply. If they do not, the bug is in the callers' code, not in the function body. Now, if the function is in a commercial library, the creators of that library may wish to keep their source code to themselves - but they'd still want to expose the precondition. Worse, the callers' code could still be at the debug stage, while the library code may be a release build - in which case, not only will the application developer not be made aware of the precondition, but it won't even be executed! The resolution is that preconditions must always be executed by the caller, not the callee. That way, caller bugs caused by violating the contract will be found, as they should. And these means that it must be possible to expose an "in" contract without exposing the implementation.I agree, but I would further argue that isolated "out" contracts should be allowed as well: * Explicitly documents what callers can expect from a library * Ensures that if the library changes (i.e. a future version changes its contracts), those who call it will report errors (when the previous contract is violated) * In the future, optimizing compilers will probably use "out" contracts to optimize code that runs after the function call.
Aug 26 2004
Couldn't you just comment out the in statement ? Or will that break the contracts ?Worse, the callers' code could still be at the debug stage, while the library code may be a release build - in which case, not only will the application developer not be made aware of the precondition, but it won't even be executedI'm not sure what can be done about this, other than slap the developer.The resolution is that preconditions must always be executed by the caller, not the callee. That way, caller bugs caused by violating the contract will be found, as they should.Ive lost you here, in what way is 'in' not behaving as you would like, or when does 'in' not catch the conditions ( besides in a release build ? ). And how can you control who 'executes' the conditions ? Charlie In article <cgl5ni$hfb$1 digitaldaemon.com>, Arcane Jill says...I would very much like this to compile: Until yesterday, this compiled, but incorrectly. Walter has now fixed this bug, but he's fixed it in such a way that it now won't compile at all. The issue is this. A function's "in" contract is a precondition with which /callers/ are expected to comply. If they do not, the bug is in the callers' code, not in the function body. Now, if the function is in a commercial library, the creators of that library may wish to keep their source code to themselves - but they'd still want to expose the precondition. Worse, the callers' code could still be at the debug stage, while the library code may be a release build - in which case, not only will the application developer not be made aware of the precondition, but it won't even be executed! The resolution is that preconditions must always be executed by the caller, not the callee. That way, caller bugs caused by violating the contract will be found, as they should. And these means that it must be possible to expose an "in" contract without exposing the implementation. Does that sound reasonable? Arcane Jill
Aug 26 2004
In article <cgl94t$j0i$1 digitaldaemon.com>, Charlie says...It would have to be done by the compiler. Currently, given the code: the compiler invisibly transforms it to: I would prefer that it instead transform it to: See what I mean? Arcane JillThe resolution is that preconditions must always be executed by the caller, not the callee. That way, caller bugs caused by violating the contract will be found, as they should.Ive lost you here, in what way is 'in' not behaving as you would like, or when does 'in' not catch the conditions ( besides in a release build ? ). And how can you control who 'executes' the conditions ?
Aug 26 2004
See what I mean?Ahh yes, thanks for clarifying. Yes that looks like a good call, and like sean said could be extended for out contracts too. Charlie In article <cglaf6$joc$1 digitaldaemon.com>, Arcane Jill says...In article <cgl94t$j0i$1 digitaldaemon.com>, Charlie says...It would have to be done by the compiler. Currently, given the code: the compiler invisibly transforms it to: I would prefer that it instead transform it to: See what I mean? Arcane JillThe resolution is that preconditions must always be executed by the caller, not the callee. That way, caller bugs caused by violating the contract will be found, as they should.Ive lost you here, in what way is 'in' not behaving as you would like, or when does 'in' not catch the conditions ( besides in a release build ? ). And how can you control who 'executes' the conditions ?
Aug 26 2004
Arcane Jill wrote:I would very much like this to compile: Until yesterday, this compiled, but incorrectly. Walter has now fixed this bug, but he's fixed it in such a way that it now won't compile at all. The issue is this. A function's "in" contract is a precondition with which /callers/ are expected to comply. If they do not, the bug is in the callers' code, not in the function body. Now, if the function is in a commercial library, the creators of that library may wish to keep their source code to themselves - but they'd still want to expose the precondition. Worse, the callers' code could still be at the debug stage, while the library code may be a release build - in which case, not only will the application developer not be made aware of the precondition, but it won't even be executed! The resolution is that preconditions must always be executed by the caller, not the callee. That way, caller bugs caused by violating the contract will be found, as they should. And these means that it must be possible to expose an "in" contract without exposing the implementation. Does that sound reasonable?Very! This also opens the doorway to finally implementing contract inheritance without having to store things in the vtbl. The first thing that came to mind is that contracts on classes accessed through an interface still need to test those contracts, even though which exact contracts are to be tested isn't even known at compile-time. If the caller was responsible for testing contracts, this would be impossible. However, this is completely counter to the spirit of both DbC and interfaces. The contract is part of the interface, not the implementation. Logically, then, interfaces need to be able to specify contracts, and methods implementing an interface must be /forbidden/ from specifying contracts of their own. (ditto for abstract classes/methods) This could potentially cause some minor problems with mix-in styled interface implementation, though: interface IFace { // contracts allowed, but no body void hello() in { ... } out { ... }; void goodbye() in { ... }; } class PartialImpl { void hello() in { ... } out { ... } body { ... } } class FullImpl : PartialImpl, IFace { void goodbye() { // no contracts allowed here ... } /* * bam. PartialImpl.hello has its own contracts, and therefore * does not satisfy IFace (unless the two happened to be * identical, but let's not go there) * * Because of this, an alias won't do. */ void hello() { super.hello(); } } In this manner, all contracts are known at compile time, can therefore be checked by the caller and not the callee, contracts and interfaces conform more closely to their intended purposes, and we even keep link compatibility between debug and release builds. -- Captain Sidetrack
Aug 26 2004
Andy Friesen wrote:... doh. This is all hogwash because testing against instance data is kind of handy. Polymorphic contracts aren't optional. Walter, how did you intend to implement contract inheritance? If they're just pasted into a method, then they can't be inherited. Implementing them as full-blown methods in their own right means three vtbl entries per method which have to stick around even in release mode lest debug/release builds fail to link. -- andyDoes that sound reasonable?Very! [stuff]
Aug 26 2004
In article <cglbl7$kdq$1 digitaldaemon.com>, Andy Friesen says...This also opens the doorway to finally implementing contract inheritance without having to store things in the vtbl. The first thing that came to mind is that contracts on classes accessed through an interface still need to test those contracts, even though which exact contracts are to be tested isn't even known at compile-time. If the caller was responsible for testing contracts, this would be impossible. However, this is completely counter to the spirit of both DbC and interfaces. The contract is part of the interface, not the implementation. Logically, then, interfaces need to be able to specify contracts, and methods implementing an interface must be /forbidden/ from specifying contracts of their own. (ditto for abstract classes/methods)But aren't classes also interfaces? And what about free functions (though I grant that inheritance issues are not a problem here)? Or were you just saying that if classes use DbC then those clauses need to be in library headers and not obscured in object code? Sean
Aug 26 2004
"Arcane Jill" <Arcane_member pathlink.com> wrote in message news:cgl5ni$hfb$1 digitaldaemon.com...I would very much like this to compile: Until yesterday, this compiled, but incorrectly. Walter has now fixed thisbug,but he's fixed it in such a way that it now won't compile at all. The issue is this. A function's "in" contract is a precondition with which /callers/ are expected to comply. If they do not, the bug is in thecallers'code, not in the function body. Now, if the function is in a commerciallibrary,the creators of that library may wish to keep their source code tothemselves -but they'd still want to expose the precondition. Worse, the callers' code could still be at the debug stage, while thelibrarycode may be a release build - in which case, not only will the application developer not be made aware of the precondition, but it won't even beexecuted!The resolution is that preconditions must always be executed by thecaller, notthe callee. That way, caller bugs caused by violating the contract will be found, as they should. And these means that it must be possible to exposean"in" contract without exposing the implementation. Does that sound reasonable?I think there's a small misunderstanding when it comes to in contracts. Parameter validation for, let's say, operating system API functions, is a requirement for it to be it release builds. That is akin to user input validation, and is not what DbC is for. DbC is for programs that, once debugged, can have the DbC removed. Anything that exposes an interface to arbitrary other code needs to keep its input validation turned on - this would include operating system APIs, DLLs, shared libraries, and COM objects. If a vendor is shipping libraries meant to be statically linked in, it would be perfectly sensible for them to produce two builds - a 'release' build with DbC turned off, and a 'debug' build with DbC on which the user uses to debug his interface to that library. This does not require that the vendor ship the source or expose the implementation. (Furthermore, there's a problem with having the caller execute the preconditions - the essential polymorphic aspect of them would be lost.) If you wish to *add* preconditions to an existing library function, and for good reason do not wish to modify the library source, the right approach is to put a wrapper around it with the DbC in the wrapper.
Aug 26 2004
In article <cglsov$tbd$1 digitaldaemon.com>, Walter says...I think there's a small misunderstanding when it comes to in contracts. Parameter validation for, let's say, operating system API functions, is a requirement for it to be it release builds. That is akin to user input validation, and is not what DbC is for. DbC is for programs that, once debugged, can have the DbC removed.I know. I didn't misunderstand.Anything that exposes an interface to arbitrary other code needs to keep its input validation turned on - this would include operating system APIs, DLLs, shared libraries, and COM objects.That is the situation /now/, yes. However, this was a feature request. If preconditions were instead to be done by the caller, that situation would change, and vendors would be able to release only one version of their library.If a vendor is shipping libraries meant to be statically linked in, it would be perfectly sensible for them to produce two builds - a 'release' build with DbC turned off, and a 'debug' build with DbC on which the user uses to debug his interface to that library.Again, this is the situation /now/. I was suggesting that it be changed.This does not require that the vendor ship the source or expose the implementation.? How can you expose the in contract without the implentation? It won't compile! If you mean that vendors may be able to expose: then is exactly what I'm asking for. If they can't, how can they possibly expose the precondition without exposing the implementation? Oh right! You mean they have to cheat. I get it: Hmmm. Maybe you should document that, if it's how it's supposed to be done.(Furthermore, there's a problem with having the caller execute the preconditions - the essential polymorphic aspect of them would be lost.)Is it essential? I've been thinking about this (though perhaps now as much as you). Okay, let's say we have a class Stream with precondition that the stream must not have been closed. Now let's say we have a class AlignedStream, deriving from Stream, with additional precondition that the input must always be in multiples of four bytes. You're saying that: should check the AlignedStream precondition, not the Stream precondition? I'm not so sure. Shouldn't a derived class always weaken, not strengthen, the precondition? That is, in the above example, AlignedStream shouldn't be deriving from Stream - or should make a runtime check or something. Can this kind of polymorphic aspect work like this? I may have misunderstood this part.If you wish to *add* preconditions to an existing library function,I don't. Arcane Jill
Aug 27 2004
"Arcane Jill" <Arcane_member pathlink.com> wrote in message news:cgmni7$1a9p$1 digitaldaemon.com...You don't need to expose the contract - the contract just has to be executed. It can be executed in compiled form by the library, so the library (compiled with DbC on) doesn't need to ship the source.This does not require that the vendor ship the source or expose the implementation.? How can you expose the in contract without the implentation?Yes. Bertrand Meyer goes through it all in his book on the topic "Object-Oriented Software Construction". He shows how it is essential for polymorphic functions to have polymorphic pre/post conditions.(Furthermore, there's a problem with having the caller execute the preconditions - the essential polymorphic aspect of them would be lost.)Is it essential?I've been thinking about this (though perhaps now as much as you). Okay, let's say we have a class Stream with precondition that thestreammust not have been closed. Now let's say we have a class AlignedStream,derivingfrom Stream, with additional precondition that the input must always be in multiples of four bytes. You're saying that: should check the AlignedStream precondition, not the Stream precondition?I'mnot so sure. Shouldn't a derived class always weaken, not strengthen, the precondition?A derived class weakens the precondition in that either the base precondition must be true OR the derived precondition. But when you have a reference to a base class, you do not know if is in reality a derived class, so you do not know which preconditions to check.
Aug 27 2004
In article <cglsov$tbd$1 digitaldaemon.com>, Walter says...If a vendor is shipping libraries meant to be statically linked in, it would be perfectly sensible for them to produce two builds - a 'release' build with DbC turned off, and a 'debug' build with DbC on which the user uses to debug his interface to that library.I see only one version of phobos.lib in my download. Does it have DbC enabled? Jill
Aug 27 2004
"Arcane Jill" <Arcane_member pathlink.com> wrote in message news:cgmrdh$1bal$1 digitaldaemon.com...In article <cglsov$tbd$1 digitaldaemon.com>, Walter says...wouldIf a vendor is shipping libraries meant to be statically linked in, ittobe perfectly sensible for them to produce two builds - a 'release' build with DbC turned off, and a 'debug' build with DbC on which the user usesNo. But it does come with source, and you can adjust the makefile to compile it with DbC on.debug his interface to that library.I see only one version of phobos.lib in my download. Does it have DbC enabled?
Aug 27 2004
Walter wrote: <snip>I think there's a small misunderstanding when it comes to in contracts. Parameter validation for, let's say, operating system API functions, is a requirement for it to be it release builds. That is akin to user input validation, and is not what DbC is for.I disagree. The end user isn't going to be calling OS API functions directly, any more than functions in the library being talked about or functions in the app itself.DbC is for programs that, once debugged, can have the DbC removed. Anything that exposes an interface to arbitrary other code needs to keep its input validation turned on - this would include operating system APIs, DLLs, shared libraries, and COM objects.<snip> Indeed. Obviously an app wouldn't pass potentially bad user input to an API if the only check is DbC. It would do user input validation first. AIUI, the OP's request is for the DbC validation to work in those situations when it should, and when it is correct to use DbC - for checking that the application (not the user) is passing valid arguments to lib functions. This is part of the Phobos philosophy, isn't it? Stewart. -- My e-mail is valid but not my primary mailbox. Please keep replies on the 'group where everyone may benefit.
Aug 27 2004
"Stewart Gordon" <smjg_1998 yahoo.com> wrote in message news:cgn0jc$1deu$1 digitaldaemon.com...Walter wrote: <snip>Yes, they do. I call OS API functions all the time in my code.I think there's a small misunderstanding when it comes to in contracts. Parameter validation for, let's say, operating system API functions, is a requirement for it to be it release builds. That is akin to user input validation, and is not what DbC is for.I disagree. The end user isn't going to be calling OS API functions directly, any more than functions in the library being talked about or functions in the app itself.Any OS API or DLL interface must consider all programs trying to connect to its functions as rogue, and must do parameter validation on them.DbC is for programs that, once debugged, can have the DbC removed. Anything that exposes an interface to arbitrary other code needs to keep its input validation turned on - this would include operating system APIs, DLLs, shared libraries, and COM objects.<snip> Indeed. Obviously an app wouldn't pass potentially bad user input to an API if the only check is DbC. It would do user input validation first.
Aug 27 2004
Walter wrote: <snip>You mean when you're doing word processing, graphic design, browsing the web, playing games or whatever, you type in random API calls to be executed? <snip>I disagree. The end user isn't going to be calling OS API functions directly, any more than functions in the library being talked about or functions in the app itself.Yes, they do. I call OS API functions all the time in my code.Any OS API or DLL interface must consider all programs trying to connect to its functions as rogue, and must do parameter validation on them.Yes. But a lib might also do its own checks as an added safety net. These might be done by either DbC or by checks in the release code. E.g. to make the lib functions fail-fast, or to translate vague zero return values into context-sensitive exceptions. Stewart. -- My e-mail is valid but not my primary mailbox. Please keep replies on the 'group where everyone may benefit.
Sep 01 2004
Walter wrote:I think there's a small misunderstanding when it comes to in contracts. Parameter validation for, let's say, operating system API functions, is a requirement for it to be it release builds. That is akin to user input validation, and is not what DbC is for. DbC is for programs that, once debugged, can have the DbC removed. Anything that exposes an interface to arbitrary other code needs to keep its input validation turned on - this would include operating system APIs, DLLs, shared libraries, and COM objects.What about the reasons I posted? Contracts are useful for optimization, and for making sure that later versions of a library haven't chosen to abandon some contracts that they used to obey.(Furthermore, there's a problem with having the caller execute the preconditions - the essential polymorphic aspect of them would be lost.)Not necessarily. As I undertsand it, we currently have contracts that work like this: void CalledFunction(<whatever>) { /* in contracts */ /* body */ /* out contracts */ } Which is good, and is polymorphic. Don't change that. What I think is that when you have a function without a body, you should *add* these tests to the caller: /* in contracts */ CalledFunction(<whatever>); /* out contracts */ This retains polymorphism but also allows us to assert things about libraries for which we don't have the source. Yeah, it means that the assert()s are run twice, but, as you note, contracts are designed for debug builds, not release builds. Plus, it lets us run contracts even if the vendor only gave us a release build. Of course, this leads us quite quickly back to the question of contracts on interfaces and on delegates. The callee could add the contracts to his own code in those cases, as well...If you wish to *add* preconditions to an existing library function, and for good reason do not wish to modify the library source, the right approach is to put a wrapper around it with the DbC in the wrapper.Yeah, but that's ugly...
Aug 27 2004
"Russ Lewis" <spamhole-2001-07-16 deming-os.org> wrote in message news:cgnpqm$1rrr$1 digitaldaemon.com...What about the reasons I posted? Contracts are useful for optimization, and for making sure that later versions of a library haven't chosen to abandon some contracts that they used to obey.That's true, contracts are possibly valuable hints for optimization.It still breaks polymorphism. If you have: class A { void foo() in { ... } body { ... } } class B:A { void foo() in { ... } body { ... } } ... A a; ... a.foo(); you'll be calling B.foo(), not A.foo(), and A.foo()'s preconditions do not apply.(Furthermore, there's a problem with having the caller execute the preconditions - the essential polymorphic aspect of them would be lost.)Not necessarily. As I undertsand it, we currently have contracts that work like this: void CalledFunction(<whatever>) { /* in contracts */ /* body */ /* out contracts */ } Which is good, and is polymorphic. Don't change that. What I think is that when you have a function without a body, you should *add* these tests to the caller: /* in contracts */ CalledFunction(<whatever>); /* out contracts */ This retains polymorphism but also allows us to assert things about libraries for which we don't have the source. Yeah, it means that the assert()s are run twice, but, as you note, contracts are designed for debug builds, not release builds. Plus, it lets us run contracts even if the vendor only gave us a release build.
Aug 27 2004
Walter wrote:It still breaks polymorphism. If you have: class A { void foo() in { ... } body { ... } } class B:A { void foo() in { ... } body { ... } } ... A a; ... a.foo(); you'll be calling B.foo(), not A.foo(), and A.foo()'s preconditions do not apply.Should they? It /is/ an A, after all. Shouldn't it be expected to behave like one? Polymorphic preconditions could (hypothetically) produce subtle bugs in code that satisfies the conditions set forth by an ancestor of A, but not A itself. (I haven't read any of Bertrand Meyer's writings, though, so I shall assume that I am wrong regardless) Also, how is DMD going to cope with inheriting a class whose source is not available? The contracts can't loosen/tighten properly if you don't know what they are. -- andy
Aug 27 2004
Andy Friesen wrote:Walter wrote:Right! It should be valid for the caller to assert A's preconditions, because the caller doesn't know about the fact that B loosened them. Likewise, the caller can assert A's postconditions, even though B may have tightened them. Frankly, I'm starting to think that this *should* be done. I'm thinking that the following code should be an error: class A { void foo(int i) in { assert(i> 0); } body {} } class B:A { void foo(int i) in { assert(i>=0); } body {} } A a = new B; a.foo(0); // assert should fail here So code, in order to work would have to do this: B b = cast(B)a; b.foo(0); // ok, uses B's preconditionsIt still breaks polymorphism. If you have: class A { void foo() in { ... } body { ... } } class B:A { void foo() in { ... } body { ... } } ... A a; ... a.foo(); you'll be calling B.foo(), not A.foo(), and A.foo()'s preconditions do not apply.Should they? It /is/ an A, after all. Shouldn't it be expected to behave like one?
Aug 28 2004
Walter wrote:I think there's a small misunderstanding when it comes to in contracts. Parameter validation for, let's say, operating system API functions, is a requirement for it to be it release builds. That is akin to user input validation, and is not what DbC is for. DbC is for programs that, once debugged, can have the DbC removed. Anything that exposes an interface to arbitrary other code needs to keep its input validation turned on - this would include operating system APIs, DLLs, shared libraries, and COM objects.I strongly disagree. The basic question here is: who is to be trusted? Should a library trust the application to do the calls correctly? This is basically a design decision: for distributed systems, like the COM objects you are talking about, I agree that every object should thoroughly check any input it gets. The individual objects are rather weakly linked with each other, so each one should take care of it's own integrity. For DLLs, though, the matter is different: The code of the DLL runs under the same priviledges as the code of the application. In principle, the application has all the power to fiddle with the data of the DLL or walk around the interface in any way it likes. It is the responsibility of the application programmer not to abuse this power. It is not up to the library to put up safeguards. Whether or not the in-contracts of a library need to be checked depends on the stability of the application. There is no difference whether it is a static or dynamic library. True, a DLL can be linked in a different version, but whatever version you use, it has to follow the correct interface. Contracts are part of the interface. If you change the interface, be prepared to recompile the application. Therefore: in-contracts should be checked by the caller, and it depends on the stability of the caller whether this check has to be performed. Any check of the user-input or other untrusted data has to be performed before the check of the in-contract.If a vendor is shipping libraries meant to be statically linked in, it would be perfectly sensible for them to produce two builds - a 'release' build with DbC turned off, and a 'debug' build with DbC on which the user uses to debug his interface to that library. This does not require that the vendor ship the source or expose the implementation.There is no point at all in shipping "debug"-compiles of a library. If the library code is correct, out-contracts and invariants need not be checked. On the other hand - no matter how correct the library is: it is up to the application developer to decide whether in-contracts need to be checked.(Furthermore, there's a problem with having the caller execute the preconditions - the essential polymorphic aspect of them would be lost.)The worry about breaking polymorphism is totally unfounded: Already, there is the rule, that in-contracts are "or"ed together in inheriting classes. If you call a method on a class reference, you can always check the in-contracts of the reference class, even if the class of the object class is a subclass of that. If the check passes, this will be fine in any case (because of the "or" rule) Furthermore: the in-contracts may only depend on public information about a class. There is no point of talking about a "contract" if one of the parties cannot check whether it is kept.
Aug 30 2004