On Wednesday, April 11, 2018 07:47:14 H. S. Teoh via Digitalmars-d-announce wrote: > On Tue, Apr 10, 2018 at 11:43:00PM -0600, Jonathan M Davis via > Digitalmars-d-announce wrote: [...] > > > IMHO, for contracts to be worth much outside of the inheritance case, > > we'd need to do something like make it so that contracts are compiled > > in based on whether the caller used -release or not rather than > > whether the callee did. > > This is what should have been done in the first place, and I'd argue > that this is the direction we should be going in. The current > implementation of contracts greatly diminish their value, though > personally I'd still use them because they convey intent better than > just sticking a bunch of asserts at the top of the function body. > > > If that were done, then there would be real value in using contracts, > > and I'd be a lot more excited about the new syntax. As it is, it seems > > like a nice improvement that's ultimately pointless. > > [...] > > I consider this as a first step in improving DbC support in D. The next > step is to make it so that in-contracts are enforced on the caller's > side rather than the callee's side. IIRC, the original version of this > DIP included something to this effect, but it was eventually taken off > in order to stay more focused in scope so that the chances of acceptance > would be higher. But I hope that eventually a future DIP would address > this more fundamental and important issue.
If we actually end up with a language improvement that makes it so that contracts are compiled in based on the caller instead of the callee, then I'll start using contracts. Until then, I'm not generally going to bother. And that reminds me, I was considering putting together a DIP to fix the situation with invariants and void initialization. Thanks to the fact that opAssign checks the state of the object prior to assigning it, you basically can't use invariants with anything that you would void initialize, which means that I basically never use invariants, and unlike in and out contracts, invariants are actually a huge boon when they're appropriate, since they insert checks with _every_ public function call, which would be a royal pain to do by hand. Because of this issue, I'd previously argued that opAssign should not check the state of the object before assigning it, but Walter rejected that, and in rare cases, you actually do care about the state of the object before assigning it, so that makes some sense, but it's a huge problem when void initialization gets involved. So, I was thinking that maybe we should have a way to indicate at the call site that an assignment should not call the invariant prior to calling opAssign in that specific case. But I haven't gotten much past that in figuring it out, since it's not all that high on my priority list. It's really annoying if you use invariants, but my solution has been to just not use them, so it's a problem but not one that actively gets in my way at the moment. It's just that I then lose out on invariants. :| - Jonathan M Davis