Subscribe to Dr. Macro's XML Rants

NOTE TO TOOL OWNERS: In this blog I will occasionally make statements about products that you will take exception to. My intent is to always be factual and accurate. If I have made a statement that you consider to be incorrect or innaccurate, please bring it to my attention and, once I have verified my error, I will post the appropriate correction.

And before you get too exercised, please read the post, date 9 Feb 2006, titled "All Tools Suck".

Sunday, February 26, 2006

I was wrong (sort of) about namespaces

As we were putting the final brush strokes on the XML 1.0 Recommendation (almost 10 years ago now--hard to believe) we started working on "namespaces for XML". At the time I was quite vocal in my opposition to namespaces on the grounds that they didn't really solve any problems, were misguided, and totally missed the point. I was also very upset, if memory serves, about the issue of using attributes to declare namespaces rather than processing instructions. It got to point where I couldn't really be constructive on the weekly conference calls, my blood presure was going up, and I just generally couldn't deal with it any more. In my mind the whole XML thing was going off the rails just as we needed to focus on the really important stuff, namely XLink. So I quit my participation in the XML Working Group, made a lot of strong statements that hopefully have been largely forgotten, took my toys and went home.

Boy was I wrong. Mostly. Sort of.

I don't know that I've ever actually apologized to anyone about this, especially Tim Bray, who was the primary driver of the namespaces mechanism. In any case--to the degree that my behavior at the time impeded the completion of namespaces or otherwise disrupted the activity, I apologize.

So what was I wrong about?

My objections to namespaces as they were being formulated (and as they subsequently got defined) were:
  1. There was no standard mechanism for defining membership of names in a namespace
  2. There was no standard mechanism for binding a given namespace to an abstract application
  3. Using attributes to declare namespaces was just wrong wrong wrong
  4. Namespaces didn't really solve the interoperation problems that people had or perceived
At the time I had just spent several years rewriting the HyTime standard (ISO/IEC 10744:1996). One of the key features of HyTime was a mechanism called "SGML Architectures" which did both of the first two things I claimed (correctly) that namespaces didn't do. Namely, it provided a way to unambiguosly bind document types (sets of named elements and attributes) to abstract applications and defined a standard way to formally declare the members of that namespace ("architectural DTDs"). It also provided a way to map instance-level element and attribute names to architectural names, the functional equivalent of using different namespace prefixes to disambiguate otherwise clashing local names.

At the time I was so deeply indoctrinated with the big-iron, big-industry, big-standard "everything must be fully defined up front" way of thinking that I just couldn't see a less formal approach working. At the time I hadn't fully gotten the less-is-more Way of the Web. So I objected to namespaces on the grounds that it was just creating this huge potential mess that wouldn't really help.

It's still true that the namespace specification, by itself, provides no formal way to define the set of names in a namespace. That is, by the namespace spec, given a name, there's no way to determine if that name is or is not a valid member of the namespace.

With just DTD's this was kind of a problem because there was no defined way to bind a DTD to a namespace (something we did do in the HyTime standard). But eventually XSD schemas (and I should think, all other XML document constraint specification mechanisms designed since the publication of the namespace spec [But not Relax as of March 2007--WEK]) did provide a way to bind document types to namespaces. This still doesn't formally define the finite set of members in a namespace but it does let you define a set of names for the namespace. The subtle difference here is that the definition of the set of names points to the namespace rather than the namespace pointing to the definition.

Think about that for a moment--the only standard-defined thing that represents a namespace (per the namespace spec) is the namespace URI--there is no requirement (or even expectation) that that URI be resolvable to any resource. A naive person (or a person steeped in big-systems declare everything think) might expect that a namespace URI would always resolve to a resource that describes the namespace as an object. From a pure engineering/mathematical completeness standpoint that seems like a reasonable thing--anything you can name should have a concrete representation: "Damnit Spock, there needs to be an object!"

So why don't namespaces have this? Simple answer: because they didn't need them in order to be useful. That's the beauty of the Web: it's agile methods at work--the simplest thing that could possibly work.

Namespaces work because by and large there's no confusion about what application a given namespace is associated with. In practice there's just not a lot of important namespaces that people use that they don't know, up front, what they're about. The full declaration bit would only be needed in a world where you are likely to encounter a namespace you've never seen and only at that point need to find out what it's about by following the namespace URI. If it was purely software doing this discovery and data finding, then having everything formally declared would be necessary but in fact it's usually humans doing the discovery and finding and just doing a Google[tm] search on the namespace URI is usually sufficient to take you to the specification that defines the semantics for that namespace. So why add one more layer of standardization to an already complicated system? Duh.

I do observe, however, that there still seems to be lots of work on web services registries and all that kind of stuff. I try to stay out of that world because it's not relevant to my day-to-day work and I don't otherwise find it interesting, but I can imagine that it's hard stuff to standardize, both technically and politically.

Which means that it was in fact quite brilliant for the namespace spec to avoid the whole issue by saying that any such stuff was "out of band".

So my first errors were in thinking that there was in fact a need for a single way to limit the membership in a namespace and a need for a central physical representation of the namespace as an object.

So what about using attributes to define namespace declarations? My (and not just my, but a number of members of the committee at the time) felt that intruding on the document author's attribute space in order to do declarative stuff was fundamentally, morally wrong and that processing instructions were there precisely to do this type of declaration. We were, of course, completely correct. But it didn't matter--the Powers that Be had a thing against processing instructions and others insisted that attributes were clearer and what not. Again, for me, not intruding on the author's space was a fundamental, inviolate princple I had learned deeply from my work on SGML and HyTime. It was an essential tenent of my technical faith and I defended it with the furvor of a True Believer.

In retrospect I see now that using attributes was the correct choice, that the namespace stuff is really intrinsic properties of the elements (and attributes) and therefore putting those properties on attributes was the best thing to do lacking a more specialized syntax. It did complicate XML processors a bit because they now have to do some special case stuff with those namespace attributes but who cares? That just affects tool implementors, not users.

About solving the interoperation problem: if I remember the discussion at the time, one of the driving use cases was a situation where an automatic processor would need to dynamically combine elements from two different input documents into a new instance while ensuring that there were no name collisions. I don't know if this use case actually exists but it seemed both bogus and irrelevant at the time. Bogus because I didn't really see where this would happen (but I can't claim any particular breadth of vision for how XML is used--I've always been clear that I represent the world of authoring and publishing). Irrelevant because in this scenario, even with namespaces, you'd have to be prepared to rewrite tags as part of the combination process (either to change namespace prefixes or to disambiguate entire tag names), so namespaces didn't really solve anything here. (And HyTime had already defined an attribute-based mechanism for mapping local tag names to fully-qualified names so why did we need namespaces?).

Again, I was right but pointlessly so. In practice its rare that namespace prefixes clash because most namespaces are well known and defined with a conventional prefix that is likely to be unique among the set of namespaces likely to be combined (again, the more general case of willy-nilly combination of unexpected stuff just doesn't much happen).

So now, in the fullness of time, I have come to fully appreciate the value, nay essentialness, of namespaces. With namespaces, as with HyTime (but with much less definitional overhead), names can be unambiguously bound to applications via namespace URIs formally associated with schemas (i.e., targetNameSpace) and by formal specifications that define the semantics associated with namespaces.

While the direction of pointing (from specification to namespace) may seem backwards, it works just find because nobody's going to define two different standards for the same namespace (at least not on purpose). That is, there seems to be pretty good clarity about what (abstract) application is associated with a given namespace.

For schemas it's not quite as clean but it still works well enough. The issue is that because there is no single standard way to point from a namespace to the formal definition of its member names (because there's no standard object that represents the namespace and that could then do the pointing), its necessary for vocabularly definitions to point to the namespaces they govern. This pointing can be indirect (via a specification that points to formal vocabularly definitions and asserts that they govern the namespace) or direct, i.e., XSD's targetNameSpace attribute.

The problem with the direct pointing is that two schema instances might point to the same namespace, creating an ambiguity about which one is the right one to use at a given moment or for a give purpose. But again, in practice, that's usually resolved by the people setting up the local system or documenting the specification or whatever. But there are times when the ambiguity is a practical problem (which I'll put in another entry before too long).

But even with this potential for ambiguity I think that the importance of unambiguous binding of documents to schemas is so great that all elements should be in a namespace.

I also think that the potential for document type modularity that namespaces coupled with XSD-schema-type features is quite great and that we, as a community, have not yet fully worked out all the issues, practicalities, and potential benefits (as evidenced by, for example, the ongoing sincere discussion of how best to apply namespaces to the DITA specification).

But I am now foursquare in favor of namespaces--they may not be perfect but they are essential and they work well enough as defined (and in any case they are what they are and aren't likely to change any time soon). If you're not using namespaces you should be--I can't see any excuse for anyone defining any set of XML elements that is not in a namespace. It should be required and it's too bad that XML, for compatibility reasons, has to allow no-namespace documents. Oh well.

Live and learn.



Blogger John Cowan said...

The problem with the direct pointing is that two schema instances might point to the same namespace, creating an ambiguity about which one is the right one to use at a given moment or for a given purpose.

Let me play the devil's advocate for a bit and change "ambiguity" to "flexibility and opportunity". On the principle of doing the simplest thing that could possibly work, it is often sensible to validate documents against different schemas at different stages of the validation process. Using a two-component model of validation ("Does this document validate against this schema?) rather than the one-component model inherited from DTDs ("Is this document self-consistent?") facilitates this approach.

Similarly, we need not bind a namespace to a single application. There are many things one can do with a document, and there is no need for there to be a single official piece of code (even locally) to process it with.

10:58 AM  
Blogger Eliot Kimber said...

I agree that there is often value in having different schemas (for example, authoring vs archiving) but that doesn't remove the inherent ambiguity. But I want to talk about that in more detail in another post.

However, in your last paragraph you are misunderstanding what I mean by "application". I don't mean the software that does the processing, I mean "application" in the sense that XML (and SGML) both mean it, namely, an abstraction that represents the intended purpose and semantics of the documents, i.e., DocBook, DITA, MathML. These are applications in this sense.

While namespaces can be used to configure the binding between elements and the specific software components used to process them for a given purpose at a given time, that's just a happy side effect of having namespaces.

6:22 AM  

Post a Comment

<< Home