The Forum for Discussion about The Third Manifesto and Related Matters

Please or Register to create posts and topics.

Codd 1970 'domain' does not mean Date 2016 'type' [was: burble about Date's IM]

I'm responding to the original post and possibly repeating material that's been given in the plethora of posts that followed it (which I haven't read yet).

Codd certainly thought of types as physical representations and that's why he chose the mathematical term domain.  But he was a bit woolly regarding the exact meaning, especially when he appeared to be confusing the terms "domain" and "attribute", as Chris has noted.

Our claim that TTM types serve exactly the same purpose as Codd's domains is based on a reasonable interpretation of what he was driving at.  In particular, values of different domains were not comparable (so SQL domains are certainly not Codd ones).  Of course in TTM  and the IM we have given a lot more detail than Codd did but I doubt we have added anything that he would have regarded as deviating from his model.  That said, I don't remember him ever giving much of an opinion on TTM.  In fact, he never seemed greatly interested in work done by other people on the RM.  And he kept saying that types are not domains to his dying day.

Hugh

Coauthor of The Third Manifesto and related books.
Quote from Hugh on October 22, 2019, 4:46 pm

I'm responding to the original post and possibly repeating material that's been given in the plethora of posts that followed it (which I haven't read yet).

Thank you Hugh. And yes there's been quite a flurry, furthermore sticking to the subject.

Codd certainly thought of types as physical representations and that's why he chose the mathematical term domain.  But he was a bit woolly regarding the exact meaning, especially when he appeared to be confusing the terms "domain" and "attribute", as Chris has noted.

When did the term "attribute" appear (in a RM context)? I see "attribute" does appear a few times in Codd 1970. Amongst the plethora you haven't read yet is a suggestion that Codd wasn't so much "confusing" those terms as consciously equating them (at least in straightforward cases). And that equating is possible because domain does not mean type.

Our claim that TTM types serve exactly the same purpose as Codd's domains is based on a reasonable interpretation of what he was driving at.  In particular, values of different domains were not comparable (so SQL domains are certainly not Codd ones).  Of course in TTM  and the IM we have given a lot more detail than Codd did but I doubt we have added anything that he would have regarded as deviating from his model.  That said, I don't remember him ever giving much of an opinion on TTM.  In fact, he never seemed greatly interested in work done by other people on the RM.  And he kept saying that types are not domains to his dying day.

It's that last sentence (which you've told us before) that concerns me. Did he simply not try to understand 'type' in any of its more modern programming language senses? Or did he understand, but still think his domain meant something different?

Quote from Dave Voorhis on October 22, 2019, 1:35 pm

Only if there is truly no distinction between interpretations of bit patterns at machine addresses can a system be considered typeless. As soon as there is some semantic distinction between the types (!) of data stored at addresses, it is (at least weakly) typed.

I think you're wrong. A language is typeless of it adds no type features to the underlying machine architecture. The semantics exist only in the hardware and the programmer's mind, not in the language.

But it's not important. My argument is still that you can build a working version of Codd's 1970 FO-RA as a data sub-language defining the domains, literals, operators and relations as set out in his paper, and you can consume the results of queries in a host language regardless of its type system (or none at all). To this point, making the data sub-language an integral part of the host language is a choice made by TTM, not a requirement. SQL took a different path, for good and sufficient reasons.

Life gets complicated when you aspire to support what Codd did not, namely an SO-RA with open expressions. TTM provides a solution, but at a high cost, by mandating a type system that is completely incompatible with all modern programming languages. You can accept TTM for what it is and persist with its arcane type system or you can contemplate a different path. Call it a DSL.

A DSL does not need a type system, because it has no operations on values other than the RA itself. A DSL can:

  • Define named domains
  • Nominate a literal type (string, number, date) for use with that domain (optional)
  • Define named relations as a set of domains, optionally with roles to resolve ambiguities
  • Define named queries in the RA as per Codd
  • Define named updates to relations as a kind of query (relational assignment)
  • Define a host language name and type for each domain/role
  • Provide a means for the host language to execute a query by name (such as a function call)
  • Optionally replace any literal by a parameter passed in from the host language
  • Optionally replace any literal by an open expression to be valuated in the host language

What you've got there is very similar to a stripped down SQL, with some rethinking of the host language interface.

 

Andl - A New Database Language - andl.org
Quote from Dave Voorhis on October 22, 2019, 11:11 am

In 1970, notions of "type" were looser and more amorphous, it seemed reasonable to have a notion of Domain for P to be defined as a type-ish thing. Now we know better. The type is the invariant; inclusion constraints support the arbitrary (and perhaps notionally variant) pool of values. True invariant "pools" are specified via type constraints.

Oh, I don't know.  As someone who mostly thinks in terms of dynamic types, for me a type is a set of values with a name, which limits the number of types to ℵ₀ rather than the unmanageable ℵ₁.  Equivalently, a predicate with a name.  So Integer is a type, and so is EvenInteger and so is PrimeNumber, and so is GoatsOwnedByAJPCrown.  And they don't have to fall into a hierarchy, either.

The type theory of dynamically typed languages is trivial: all variables or other elements of source code have the same static type.

Quote from johnwcowan on October 23, 2019, 2:17 am
Quote from Dave Voorhis on October 22, 2019, 11:11 am

In 1970, notions of "type" were looser and more amorphous, it seemed reasonable to have a notion of Domain for P to be defined as a type-ish thing. Now we know better. The type is the invariant; inclusion constraints support the arbitrary (and perhaps notionally variant) pool of values. True invariant "pools" are specified via type constraints.

Oh, I don't know.  As someone who mostly thinks in terms of dynamic types, for me a type is a set of values with a name, which limits the number of types to ℵ₀ rather than the unmanageable ℵ₁.

As someone who mostly thinks in terms of parametric/polymorphic struct types (of which a relation is a particular shape), limiting the number of values (you don't mean "number of types"?) to ℵ₀ seems almost laughable. That's one of the reasons I just don't see that simple set theory intersections/unions is adequate; and why the whole IM 'project' seems pointless.

  Equivalently, a predicate with a name.  So Integer is a type, and so is EvenInteger and so is PrimeNumber, and so is GoatsOwnedByAJPCrown.  And they don't have to fall into a hierarchy, either.

"[not] have to fall into a hierarchy" is sensible. We just draw a "pool of values" from some type.

The type theory of dynamically typed languages is trivial: all variables or other elements of source code have the same static type.

Trivial? <goggle> You still have to figure out with (say) numeric operations what type of result (NAT/INT/FLOAT/RAT/etc) to generate from the type of the arguments. Without a hierarchy of numeric types, that's harder. If you're subtracting two NATs, do you assume the result is INT, or do you wait to see if you get a negative result? If you're adding/multiplying two INT32s, do you assume the result is INT64, or do you wait to see if the result overflows 32 bits? etc, etc.

Quote from Dave Voorhis on October 22, 2019, 12:13 pm
Quote from AntC on October 22, 2019, 12:04 pm
Quote from Dave Voorhis on October 22, 2019, 11:49 am
Quote from Erwin on October 22, 2019, 11:29 am

By now I'm pretty convinced one of the things Codd had in mind when he wrote about "identifying attributes (/attribute values) by domain name" was exactly for the purpose of "not comparing weights to lengths" and the like.

That's possible, but it's also possible that when Codd wrote the original paper he simply didn't think it through.

It's easy to assume such a landmark work was meticulously crafted by a genius who thought of everything, but that's only because it turned out to be a landmark work. That has no doubt retroactively imbued every passing remark with significance that it doesn't deserve. Like most academic and research papers, Codd 1970 was almost certainly written in a hurry under deadline pressure and page-count constraints, and thus given no more thought than millions of other papers that are tossed out and forgotten. I.e., some, but much left un- or hastily- considered.

In other words, trying to mine Codd 1970 for modern meaning (or great insights which we will surely discover if we read it again! Etc... Not.) beyond the obvious (the RM itself) is, I think, unproductive.

Fair points. They apply just as much to Date's interpretation/claims for Codd 1969/1970; and for his critiques/blaming on those papers.

I'm dissatisfied with SQL's treatment of types. I'm dissatisfied with TTM's treatment. (I guess TTM minus multiple PossReps wouldn't be coherent.) I don't see either as 'necessary' to support thea relational model. Most theoretical work on RMs takes domains/pools of values for granted/as uninteresting. I'm casting about for glimpses of other possibilities.

You might have to invent them. Most of computer science and engineering is a result of someone being dissatisfied with X's treatment of Y.

OK. Starter for 10 ... I'll begin at the end and work back to how I got there. (This is contra the quote at Ch 1 of TIRT.)

Quote from AntC on October 22, 2019, 11:38 am

I must say that writing/reading REL{TUP{S# 4, P# 4, QTY 4}} is far more ergonomic than REL{TUP{S# S#('S4'), P# P#('P4'), QTY 4}}. Something like SNAME NAME('SMITH') has always struck me as excessive circumlocution. Doubtless there's some pedagogical significance, but if we do away with multiple PossReps, we can surely do away with some of the clutter.

In fact, relation expressions could be simpler than that. If I'm going to eschew multiple PossReps, I might as well go whole hog and eschew Selectors. Then I don't need REL, TUP: I subsume relations under more general set expressions: {... , ... , ... , ...} expresses a set. The syntactic context tells me whether it's a set of <A, T, v>s (a tuple expression) or a set of tuples (a relation expression).

Ah, but REL has an optional heading as well as the tuples. I subsume that under a more general: any expression can have a type annotation, introduced by :: for definiteness. So my relation expression/statement is:

SP := {{S# 4, P# 4, QTY 4}} :: {{S#, P#, QTY}};  -- type annotation redundant in this example

The type says this is a set of sets of three domains. A domain is given by a simple name. The expression puns on the domain name: S# 4 is value 4 in domain S#.

To declare domains (I'll assume there's already the familiar INT with the familiar equality, comparison, arithmetic operations; I'll explain below where that comes from)

DOMAIN S# RENAMES INT DERIVES {Eq, Ord};

DOMAIN QTY RENAMES INT DERIVES {Eq, Ord, Arith, ToINT, FromINT};

DOMAIN P# RENAMES INT DERIVES {Eq, Ord};

DOMAIN component_P# RENAMES P# DERIVES ALL;

DOMAIN assembly_P# RENAMES P# DERIVES ALL;

The RENAMES says the two domains have the same pool of values, but a distinct name. The DERIVES says those operations are supported for equality testing/ordering values within the same domain. (But I can't compare S# 4 to INT 4. Arguably, all domains should support Eq, as per RM Pre 8.) Arith says I can do arithmetic between QTYs. ToINT says I can cast QTYs to INT, so that I can multiply a QTY by a Weight, etc. FromINT says I can cast some calculated result back to QTY. I can't cast S# to/from INT.

DERIVES ALL is a shorthand for supporting all the operations of the renamed-from domain (P# in those examples), not all the operations of the ultimate renamed-from (INT).

INT is a system-supplied domain. System-supplied domains are just user-defined domains predeclared/supplied by the compiler implementor, nothing special about them. The D might define syntactic shorthands to express values in those domains, but the denoted values are just as if user-defined.

DOMAIN BOOL = FALSE | TRUE DERIVES {Eq, Ord};   -- example enumerated domain, in sum-of-product style

For enumerated domains like that, the compiler can figure out how to overload the operations in Eq, OrdFALSE < TRUE because FALSE appears earlier in the enumeration. For more complex domains, or more complex operations, there'll be low-level code to implement the overloading of operations.

QTY5 := QTY 5; -- no type annotation

Is a valid assignment: the inferred domain for variable QTY5 is QTY.

UPDATE SP : {QTY := QTY5};

Is a valid statement: it assigns QTY 5 to the QTY domain of all tuples in relvar SP.

UPDATE SP WHERE S# = S# 4: {QTY := QTY + QTY5};

Is a valid statement, exhibiting 'open expressions' in which a bare domain name (S# = ...QTY + ...) ranges over that domain in the tuples being updated; whereas for values, the domain must be given. Except ...

UPDATE SP WHERE S# = 4 : {QTY := 5};

Hmm a 'liberal' D might support that: there's enough syntactic context to infer the 4 must be in domain S#, the 5 must be in domain QTY. Note that in the absence of context, bare 4, 5 is not INT nor RAT nor FLOAT nor S#, QTY, etc. It's polymorphic: awaiting more context to fix its domain. A tutorial D would not accept that, because (apparently) there's some pedagogic point to make.

As for inheritance ...

  • There's a form of inheritance in the DOMAIN ... RENAMES ... DERIVES {...} decl: a domain inherits supported operations from the domain it's renamed from.
  • There's a form of inheritance (not shown) in those supported operations: the decl for Arith operations can insist all domains it supports already support Ord.
  • Specialisation-by-Extension is already supported by the RM, needing no subsumption, modification, etc: a Salaried Employee is represented by a tuple in the Salary relvar with a Foreign Key to a tuple in the Employee Relvar.
  • Specialisation-by-Constraint is not supported, not wanted, not needed. You can declare constraints on/between relvars in the usual way. That doesn't change the type of the relvar, or of tuples within its body.
  • Most Specific Type not needed: all values have the type as declared or inferred from their denoting expressions. (In fact in the absence of type annotations, an expression's type is initially inferred as the most general consistent with the expression. That might get refined from surrounding syntactic context.)

Uh-oh. What am I going to write about for the next 499 pages?

Quote from dandl on October 22, 2019, 11:19 pm
Quote from Dave Voorhis on October 22, 2019, 1:35 pm

Only if there is truly no distinction between interpretations of bit patterns at machine addresses can a system be considered typeless. As soon as there is some semantic distinction between the types (!) of data stored at addresses, it is (at least weakly) typed.

I think you're wrong. A language is typeless of it adds no type features to the underlying machine architecture. The semantics exist only in the hardware and the programmer's mind, not in the language.

It's not my personal terminology but a shift -- over the last decade or so at least -- in the vernacular of discourse in language circles. Some years ago, "typeless" would have been casually used for languages like BCPL, Forth and (most) assembly languages. Now they're generally (but, admittedly, not universally -- there are a few terminological holdouts :-) described as weakly typed, because there is at least some semantic distinction (even if entirely human-operated) between data types. This shift no doubt derives from a desire to clearly distinguish such languages from, say, formal calculi that are truly typeless.

In a given language, distinguished operator semantics may exist only in the hardware but if exposed by the language enough to say, e.g., "this is integer addition" vs "this is floating point addition", then it's typically described as weakly (perhaps very weakly) typed.

A formal calculus where there are only functions, parameters and arguments but no notion of "kinds" of arguments at all would be described as typeless.

That said, I fully appreciate that there could conceivably be a typeless database (sub)language, in which attributes only reference abstract values that are completely opaque to the language aside from being able to test them for equality.

I'm the forum administrator and lead developer of Rel. Email me at dave@armchair.mb.ca with the Subject 'TTM Forum'. Download Rel from https://reldb.org
Quote from AntC on October 23, 2019, 6:29 am
Quote from Dave Voorhis on October 22, 2019, 12:13 pm
Quote from AntC on October 22, 2019, 12:04 pm
Quote from Dave Voorhis on October 22, 2019, 11:49 am
Quote from Erwin on October 22, 2019, 11:29 am

By now I'm pretty convinced one of the things Codd had in mind when he wrote about "identifying attributes (/attribute values) by domain name" was exactly for the purpose of "not comparing weights to lengths" and the like.

That's possible, but it's also possible that when Codd wrote the original paper he simply didn't think it through.

It's easy to assume such a landmark work was meticulously crafted by a genius who thought of everything, but that's only because it turned out to be a landmark work. That has no doubt retroactively imbued every passing remark with significance that it doesn't deserve. Like most academic and research papers, Codd 1970 was almost certainly written in a hurry under deadline pressure and page-count constraints, and thus given no more thought than millions of other papers that are tossed out and forgotten. I.e., some, but much left un- or hastily- considered.

In other words, trying to mine Codd 1970 for modern meaning (or great insights which we will surely discover if we read it again! Etc... Not.) beyond the obvious (the RM itself) is, I think, unproductive.

Fair points. They apply just as much to Date's interpretation/claims for Codd 1969/1970; and for his critiques/blaming on those papers.

I'm dissatisfied with SQL's treatment of types. I'm dissatisfied with TTM's treatment. (I guess TTM minus multiple PossReps wouldn't be coherent.) I don't see either as 'necessary' to support thea relational model. Most theoretical work on RMs takes domains/pools of values for granted/as uninteresting. I'm casting about for glimpses of other possibilities.

You might have to invent them. Most of computer science and engineering is a result of someone being dissatisfied with X's treatment of Y.

OK. Starter for 10 ... I'll begin at the end and work back to how I got there. (This is contra the quote at Ch 1 of TIRT.)

Quote from AntC on October 22, 2019, 11:38 am

I must say that writing/reading REL{TUP{S# 4, P# 4, QTY 4}} is far more ergonomic than REL{TUP{S# S#('S4'), P# P#('P4'), QTY 4}}. Something like SNAME NAME('SMITH') has always struck me as excessive circumlocution. Doubtless there's some pedagogical significance, but if we do away with multiple PossReps, we can surely do away with some of the clutter.

In fact, relation expressions could be simpler than that. If I'm going to eschew multiple PossReps, I might as well go whole hog and eschew Selectors. Then I don't need REL, TUP: I subsume relations under more general set expressions: {... , ... , ... , ...} expresses a set. The syntactic context tells me whether it's a set of <A, T, v>s (a tuple expression) or a set of tuples (a relation expression).

Ah, but REL has an optional heading as well as the tuples. I subsume that under a more general: any expression can have a type annotation, introduced by :: for definiteness. So my relation expression/statement is:

SP := {{S# 4, P# 4, QTY 4}} :: {{S#, P#, QTY}};  -- type annotation redundant in this example

The type says this is a set of sets of three domains. A domain is given by a simple name. The expression puns on the domain name: S# 4 is value 4 in domain S#.

To declare domains (I'll assume there's already the familiar INT with the familiar equality, comparison, arithmetic operations; I'll explain below where that comes from)

DOMAIN S# RENAMES INT DERIVES {Eq, Ord};

DOMAIN QTY RENAMES INT DERIVES {Eq, Ord, Arith, ToINT, FromINT};

DOMAIN P# RENAMES INT DERIVES {Eq, Ord};

DOMAIN component_P# RENAMES P# DERIVES ALL;

DOMAIN assembly_P# RENAMES P# DERIVES ALL;

The RENAMES says the two domains have the same pool of values, but a distinct name. The DERIVES says those operations are supported for equality testing/ordering values within the same domain. (But I can't compare S# 4 to INT 4. Arguably, all domains should support Eq, as per RM Pre 8.) Arith says I can do arithmetic between QTYs. ToINT says I can cast QTYs to INT, so that I can multiply a QTY by a Weight, etc. FromINT says I can cast some calculated result back to QTY. I can't cast S# to/from INT.

DERIVES ALL is a shorthand for supporting all the operations of the renamed-from domain (P# in those examples), not all the operations of the ultimate renamed-from (INT).

INT is a system-supplied domain. System-supplied domains are just user-defined domains predeclared/supplied by the compiler implementor, nothing special about them. The D might define syntactic shorthands to express values in those domains, but the denoted values are just as if user-defined.

DOMAIN BOOL = FALSE | TRUE DERIVES {Eq, Ord};   -- example enumerated domain, in sum-of-product style

For enumerated domains like that, the compiler can figure out how to overload the operations in Eq, OrdFALSE < TRUE because FALSE appears earlier in the enumeration. For more complex domains, or more complex operations, there'll be low-level code to implement the overloading of operations.

QTY5 := QTY 5; -- no type annotation

Is a valid assignment: the inferred domain for variable QTY5 is QTY.

UPDATE SP : {QTY := QTY5};

Is a valid statement: it assigns QTY 5 to the QTY domain of all tuples in relvar SP.

UPDATE SP WHERE S# = S# 4: {QTY := QTY + QTY5};

Is a valid statement, exhibiting 'open expressions' in which a bare domain name (S# = ...QTY + ...) ranges over that domain in the tuples being updated; whereas for values, the domain must be given. Except ...

UPDATE SP WHERE S# = 4 : {QTY := 5};

Hmm a 'liberal' D might support that: there's enough syntactic context to infer the 4 must be in domain S#, the 5 must be in domain QTY. Note that in the absence of context, bare 4, 5 is not INT nor RAT nor FLOAT nor S#, QTY, etc. It's polymorphic: awaiting more context to fix its domain. A tutorial D would not accept that, because (apparently) there's some pedagogic point to make.

As for inheritance ...

  • There's a form of inheritance in the DOMAIN ... RENAMES ... DERIVES {...} decl: a domain inherits supported operations from the domain it's renamed from.
  • There's a form of inheritance (not shown) in those supported operations: the decl for Arith operations can insist all domains it supports already support Ord.
  • Specialisation-by-Extension is already supported by the RM, needing no subsumption, modification, etc: a Salaried Employee is represented by a tuple in the Salary relvar with a Foreign Key to a tuple in the Employee Relvar.
  • Specialisation-by-Constraint is not supported, not wanted, not needed. You can declare constraints on/between relvars in the usual way. That doesn't change the type of the relvar, or of tuples within its body.
  • Most Specific Type not needed: all values have the type as declared or inferred from their denoting expressions. (In fact in the absence of type annotations, an expression's type is initially inferred as the most general consistent with the expression. That might get refined from surrounding syntactic context.)

Uh-oh. What am I going to write about for the next 499 pages?

Great start, really. It's good. You could remove the parting quip, provide an introduction and background (citing Cardelli, Darwen, Date, Hindley, Milner, Reynolds, whoever), show the inheritance bits that are not shown, maybe compare canonical examples in the IM to your M (e.g., square/rectangle, circle/ellipse, etc.), provide proof of unambiguity of inference or a mechanism to detect and clarify ambiguity, finish with a nice summary suggesting further work, and you've got yourself a publishable paper. I think you could probably stuff it into five standard pages; three if you're lucky (and terse.) Welcome to academia!

Get some traction for it (and your other papers to inevitably follow) and ere long you'll be thinking about writing a book. The publisher might give you a target page count (or you might feel obligated to deliver a certain fatness of tome) which you'll either have to stretch or compress to fill. Have fun!

No, really. It's a good start.

I'm the forum administrator and lead developer of Rel. Email me at dave@armchair.mb.ca with the Subject 'TTM Forum'. Download Rel from https://reldb.org
Quote from Dave Voorhis on October 23, 2019, 8:30 am

That said, I fully appreciate that there could conceivably be a typeless database (sub)language, in which attributes only reference abstract values that are completely opaque to the language aside from being able to test them for equality.

That's my point. [You also need literals if you are to match Codd.] But it only gets you as far as the FO-RA. For the SO-RA and open expressions a type system is strongly recommended.

We are so used to munging two quite different languages together. we've forgotten it was not the only choice.

Andl - A New Database Language - andl.org
Quote from AntC on October 22, 2019, 9:27 pm
Quote from Hugh on October 22, 2019, 4:46 pm

I'm responding to the original post and possibly repeating material that's been given in the plethora of posts that followed it (which I haven't read yet).

Thank you Hugh. And yes there's been quite a flurry, furthermore sticking to the subject.

Codd certainly thought of types as physical representations and that's why he chose the mathematical term domain.  But he was a bit woolly regarding the exact meaning, especially when he appeared to be confusing the terms "domain" and "attribute", as Chris has noted.

When did the term "attribute" appear (in a RM context)? I see "attribute" does appear a few times in Codd 1970. Amongst the plethora you haven't read yet is a suggestion that Codd wasn't so much "confusing" those terms as consciously equating them (at least in straightforward cases). And that equating is possible because domain does not mean type.

Our claim that TTM types serve exactly the same purpose as Codd's domains is based on a reasonable interpretation of what he was driving at.  In particular, values of different domains were not comparable (so SQL domains are certainly not Codd ones).  Of course in TTM  and the IM we have given a lot more detail than Codd did but I doubt we have added anything that he would have regarded as deviating from his model.  That said, I don't remember him ever giving much of an opinion on TTM.  In fact, he never seemed greatly interested in work done by other people on the RM.  And he kept saying that types are not domains to his dying day.

It's that last sentence (which you've told us before) that concerns me. Did he simply not try to understand 'type' in any of its more modern programming language senses? Or did he understand, but still think his domain meant something different?

There's a great deal of material on Codd's confusing writings re "domain" in Chris's recent book E.F. Codd and Relational Theory.  Equating domain and attribute doesn't work, as Codd himself acknowledged, when two attributes are defined on the same domain/type.  He clearly distinguished between domains and "columns" in his 1992 RM/V2 book.

I can't authoritatively answer your last question but the RM/V2 book has in Chapter 2: "Each domain is declared as an extended data type, not a mere basic data type."  And in Chapter 3: "The DBMS supports calendar dates, clock times, and decimal currency as extended data types ..." followed by a definition headed RT-3 User-defined Extended Data Types" (the text under this heading doesn't define the term at all, just says they must be supported).

I think I should withdraw my "to his dying day" assertion.  Sorry for not thinking of checking RM/V2 before I repeated it here.  It seems that he did eventually buy into the domain = type equation to a large extent, but his prohibition of the use of "basic data types" as domains is telling, I think.

Hugh

Coauthor of The Third Manifesto and related books.