In a message dated Fri, 25 Aug 2006, Mark J. Reed writes:

OK, I admit I wasn't thinking about things from a DBC perspective, and
misunderstood "DBC" to be a reference to some database module.  I here
am new and I didn't have context.  My bad.

But if we're talking design-by-contract, I don't see how "Array is
Array::Const" can work, either, since I consider the inability to
modify the elements of a constant array an explicit part of its
contract.

Well, usually you don't specify things an object *can't* do as part of its contract, unless those things would be judged harmful if allowed. (See below).

You might specify the contract of the ConstArray by saying that after any of the methods offered have been called, particular values will be unchanged--but that feature would maintain for non-constant subclasses. In other words, .elems could be specified at the constant superclass level, and its contract might say that .elems won't modify the elements, but that part of the .elems POST will maintain even in non-constant subclasses. A rw accessor, on the other hand, would not even be specified in the constant superclass, so the ConstArray contract would have nothing to say about modification.

Therefore, if we're supporting DBC, I would say that Array and
Array::Const should not have an is-a relationship at all, but should
be sibling classes, inheriting from an abstract sequence-type parent
class whose definition makes no statements one way or the other about
modifications to elements.

Sure. One *could* write a superclass, say "AbstractArrayThing", that could not be instantiated and would have no mutating methods, and have its PRE and POST blocks written as I mentioned above. The ConstArray would be a subclass that would simply add a constructor. You could specify its ongoing constedness explicitly by a class invariant block (not currently specified in Synopses, but such a thing often exists in DBC and could be constructed from a combo of ENTER and LEAVE at the class level) saying that the array will still be the same array before and after every method call.

I think that probably makes most sense and avoids the "Array isa ConstArray" cognitive dissonance. But then people would have to get into the habit of writing "AbstractArrayThing" when they want to allow for constant arrays to be passed in. That way lies the madness of Java where you're constantly writing factories to warp something so that it conforms to the API of this other thing merely because it happens to live in the wrong part of the class heirarchy.

I think Larry nailed it with his observation about the difference between class and role and trait. 'Constant' is a trait of another type, not a type into itself.

Trey

Reply via email to