Types and Updates

Home  RSS

2001
2002
2003
2004
2005
2006
2007
Letras
Libros
Pensar
Cosas

Inheriting update operators

In An Introduction to Database Systems, C.J. Date, Chapter 19, Read-Only vs. Update Operators (page 637), the book discusses the topic mentioned in the section, and then a little later discusses the notion of rejecting update operator inheritance.

What this means is simply the following, given in C# syntax if you will forgive me.

class Ellipse { Length X { get { return x; } set { x = value; } } ... }
class Circle: Ellipse { ... }

The explanation given is that the set method for the X property should not be available in the Circle class, as this might lead to circles with different X and Y lengths. Which is, of course, a violation of the constraint that makes circles circles in the first place.

I argue that updates are operators, and operators should be inherited, even if they may modify state. The update method is really a shorthand for creating a new value of the same type with a modified member and assigning it to itself. So, the following three pieces are really equivalent.

Ellipse e1 = new Ellipse(10, 20);
e1.X = 5;
...
Ellipse e2 = new Ellipse(10, 20);
e2 = new Ellipse(5, e2.Y);
...
Ellipse e3 = new Ellipse(10, 20);
e3 = e3.ReturnCopyWithNewX(5);

If we were willing to not use the first syntax, we could very well use the third variation on a circle with the same results.

Circle c = new Circle(10);
Ellipse e = c.ReturnCopyWithNewX(5);

In-place update syntax

The above may be correct, but the first way of writing code is more convenient from a thought process point of view. It is easier to think of 'updating a variable' than 'creating a modified version of a value'. Of course, this breaks down in the case of updating a single axis of an ellipse, but given our current object model, the following is still pretty convenient.

class Ellipse { ... Color Background { get { return color; } set { color = value; } } }
Circle c3 = new Circle(10);
c3.Background = Color.Red;

If there are no subtypes that have a specific constraint involving the background color of an ellipse, there is no reason why the snippet shown above should not be accepted.

More generally, when subtypes do not impose a constraint on a given property, the 'update-in-place' syntax is acceptable for that property, for the base type and the subtypes. If this is not the case, then the developer will need to deal with the possibility of an update changing the most-specific types and use variables typed accordingly.

Given this rule, it is reasonable to expect that a tool could be able to enforce it, rather than passing on the burder to data modelers. But this is different from saying 'update operators should not inherit.'

Final model

So, the final model for our colored ellipses and circles might look like this.

class Ellipse
{
  Ellipse(int x, int y) { this.x = x; this.y = y; }
  int X
  {
    get { return this.x; }
    // A setter should be rejected by the implementation, as it
    // could lead to violations because a subtype has a constraint
    // on this property.
  }
  Ellipse CopyWithX(int x) { return new Ellipse(x, this.y); }
  
  // Symmetrical for y.
  
  Color Background
  {
    get { return this.background; }
    set { this.background = value; }
    // No constraints care about background, in-place update syntax is fine.
  }
}

class Circle: Ellipse
  /* made-up syntax */
  constraint this.X == this.Y
{
  Circle(int radius) { this.x = this.y = radius; }
  // Everything that is inherited is valid.
}