Moving the deck chairs around the titanic

In a recent post, Tom Beale argued that one of the central planks of good object design is a principle he called the FOPP (fundamental ontology property principle) principle:

As a fundamental principle, all properties defined on any given type in any ontology or information model must have the potential to be true for every instance of this particular type, at some point in its lifetime.

I think, after reflection, I’m going to have to disagree. And not just because of the name; it’s not that I don’t want to have foppish objects. No, it’s more than that. My first issue, which I made as a comment on Tom’s post is that the definition is still too loose to be of use.

Tom offered as an example, the property “wingspan” on a class of Animal; this, he claimed, clearly violated the principle. Well, ok, I guess that’s reasonable. So let’s be a bit more challenging. How about the property “legCount”? Is legCount a good one to be on the Animal Class? I’m not sure. I sure don’t think Tom’s rule helps me figure it out either. I’m going to start by interpreting as “apply” rather than “be true”. But still – does it have the potential to apply to all instances? Does a snake have 0 legs? Or is it an irrelevant concept on a snake? Does a kangaroo have 2 legs and 2 arms or 4 legs? I guess we’d need a good ontological definition of legs before we could figure that out. And, btw, we don’t even know what an instance of Animal is – is an instance of Animal a species, or an individual beast? I think that might influence the answer too.

I don’t know the answer, because I think it depends on what you’re trying to do.

And there’s the rub: it depends on what you’re trying to do.

Which is where it suddenly stops sounding so easy (not that it did). So let’s go back to nullFlavor, which is our favourite little poster child for this argument. Now Tom says that he’d like a Quantity class that is used for the following:

  • A – uses Quantities to do statistical analysis;
  • B – represents Quantities in data captured from user application screens or devices in an EHR system;
  • C – uses Quantities to represent lab test reference range data, as found in a typical lab test handbook.

Tom claims that the concept of nullFlavor only applies to #B – because clearly you would never perform statistical analysis on data captured from users. Err. Right. Actually, I asked Tom about this and he said that you’d sanitize the data first before analysis (no, but that’s a separate discussion). But still, let’s grant that, and say that therefore we’ll take nullFlavor off this quantity type so you can define it and use in the hypothetical absence of unsureness.

But hang on – what do we do about use case #B now? Well, it pretty much comes down to two different approaches. You can take the HL7 v3 road, and define a “mixin”. That’s a class that extends it’s parameter type class. When I teach the v3 data types, the concept of a mixin is the single most difficult thing to cover. It’s such a simple concept to describe:

When we use type Quantity here, we’ll just add the nullFlavor to it

Easy to describe… but not at all easy to implement. I’ve never seen such a beast quite like that. AOP comes close, and C# has something close. Supposedly ADA does too – but I’ll never use that. The rest of us are stuck with real o-o languages where close enough is not good enough (anyone who’s stared cluelessly at an arcane compiler error about parameter type mismatches will know what I mean). In XML it comes naturally – but if you want to model the XML in some class language (UML, say), what are you going to do?

Alternatively, you can do what openEHR does, and wrap type A in a wrapper class that carries the nullFlavor. See, this is good because it avoids the mystifying questions a mix-in raises, and still means that

When we use type Quantity here, we’ll just add the nullFlavor to it by instead using a thingy that has the nullFlavor and then the Quantity.

All well and good. We now have an implementable solution based on this hypothetical ontologically clean class definition (though we’ve pretty much foregone being able to treat cases which don’t have a nullFlavor and cases which can’t have a nullFlavor interchangeably- this wrapper thing is in the way now). But the clean definition means nothing to me when I implement. Because I can’t go to my customers and say, “Oh, yes, this particular combination of circumstances isn’t something that could potentially be true all the time, so I can’t think about it.” No, indeed. My rule of thumb when programming is that something that happens one in a million cases will arise on a weekly basis across the deployed code base.

Given Tom’s design, instead of dealing with this cleanroom “Quantity” object, I’m just going to end up holding on to this wrapper class instead, so I can handle the few weird cases where I do positively need this nullFlavor. So much for clean design.

The problem comes from this “doing” thing: clean theory doesn’t make for clean implementations. All you can do is move the deck chairs around the Titanic (or see my second rule of interoperability).

p.s. A note about ISO 21090: there are attributes in there that violate the FOPP principle, and that I would’ve liked to go away (HXIT, for instance). But NullFlavor itself isn’t one of them. It’s ubiquitious presence is not an embarrassment to be subtracted away later; instead, it’s a positive statement of value. I understand why people (including Tom) resist that notion, but ISO 21090 does at least offer a single consistent solution to bad data across the whole implementation space. (Some of the particular nullflavors, on the other hand, clearly violate the FOPP principle, and mainly because of modeling laziness too).



  1. Thomas Beale says:

    Re: the FOPP. You are right, it should say ‘must apply’ not ‘must be true’; I corrected the original post. However, the argument about legCount doesn’t affect the FOPP. An underlying assumption is that the modeller knows what he/she/they means by each property. However ‘leg’ is defined, it must make sense on whichever class it is defined on, whose meaning in turn must be clear to the modeller. If the modeller(s) don’t know what they even mean by class or property names, then all bets are off. If they are in the business of making up names for both, as we often are in IT, then they need to stick to that definition in the sense of the FOPP applied to all relevant instances.

    Re: null-flavours and cases A/B/C: you misquoted me “nullFlavor only applies to #B – because clearly you would never perform statistical analysis on data captured from users”. I never said that statistical analysis isn’t performed on data captured from users, of course it can be. But a typical situation is to use data quality makers in captured data to remove bad data, and keep good data, on which a statistical analysis is performed. For the latter, you don’t need any data quality markers.

    A mixin is easy, and is what I briefly described as the ‘inheritance’ approach with the ‘StatisticalQuantity’ example, which is a mixin of a Quantity type and a ‘StatisticalValue’ type or whatever is required to provide that statistical semantics. Doing it with Quantity to provide nullFlavor would require a class ‘AcquiredDataItem’ containing the nullFlavor and related properties & methods. You would then create the mixin by inheriting AcquiredDataItem into a new class AcquiredQuantity, or however you wanted to call it. Programmers would then have access to both this type, where needed, and to the basic Quantity type as well.

    There is nothing wrong with the mixin approach except that you end up with a lot of types. If the behaviour of the mixin is the same for all receiver descendants, then a wrapper or generic class will reduce the number of classes. The upside of the mixin approach is that instances of the mixin classes are substitutable for those of the original class, i.e. an AcquiredQuantity is-a Quantity, which may be something someone wants.

    A better solution for some will be a generic type, i.e. AcquiredDataItem , from which you can get AcquiredDataItem , AcquiredDataItem and so on.

    I’m not proposing that the method of connecting context and use-case specifics like data acquisition values (NF) or anything else be normatively specified in HL7 or any other standard. What I am saying is that until the core, universal semantics of classes like Quantity are separated out from those other semantics, you get two serious problems:

    #1: it makes it harder for people to agree on the specification, because all the classes have more things mixed up and possibly co-dependent; it’s just more complicated.

    #2: you get the HL7v3 problem, i.e. you have to go around ‘profiling’ classes (getting rid of irrelevant stuff) for your actual use case (commonly known as upside-down or subtractive modelling), or even just to get a version of the class representing the universal semantics.

    In short, HL7v3 class models, including ISO 21090 will only improve when they stop trying to define properties corresponding to all possible use cases, in base classes in the model. The models need to be rebuilt using normal additive OO semantics, using the FOPP as a guide (it’s not that it can’t be broken, but that must be done consciously of the consequences).

  2. Lloyd McKenzie says:

    HXIT meets Thomas’s FOPP principle. The timestamp and the reference to a ControlAct always apply to every object at some point in their lifetime. In fact, they apply as soon as the object is first recognized by a system because there’s an implicit ControlAct associated with that recognition. (The fact a system might not track or assign an id to the ControlAct doesn’t mean it doesn’t exist, so it still falls within the term “apply”.)

    Is there an assertion that NullFlavor (or any other RIM or datatypes element) doesn’t follow FOPP? I can’t think of a data element that doesn’t have the potential to be ‘unknown” at some point in its lifetime . . .

  3. Gunther Schadow says:

    Thanks Grahame for this neat write-up. I remember the days when this was hotly fought over with Thomas between 5 and 10 years ago. I was so relieved when you showed up and took the discussion over. I double checked the post date of your blog post and am surprised that this old discussion is still going on, how glad I am that you took it over for all those long years! THANK YOU Grahame!!

Leave a Reply

Your email address will not be published. Required fields are marked *

question razz sad evil exclaim smile redface biggrin surprised eek confused cool lol mad twisted rolleyes wink idea arrow neutral cry mrgreen


%d bloggers like this: