The Forum for Discussion about The Third Manifesto and Related Matters

Please or Register to create posts and topics.

TTM without tuples

PreviousPage 6 of 9Next

Thank you for the responses to my posting.

The Third Manifesto provides essentially 2 things.  Firstly a formal logical model (expressed as a set of prescriptions, and a set of proscriptions).  Secondly a syntax for expressing things in terms of that model.  The model is about relations and databases, and usually called the TTM model.  The syntax is called Tutorial D.  Date & Darwen's books make clear that other syntaxes than Tutorial D could be devised to express and use the TTM model.  (In my case, RAQUEL is just another such syntax.  I'd like to have a graphical version of it, which would then be yet another syntax).

Date & Darwen also make clear that the TTM model is nothing to do with how it is physically implemented; it's a purely logical model.

My intent in my contribution was to consider solely the TTM logical model - not any syntax, and not any physical implementation.  I'm sorry if I’ve not made that very clear.

Because a logical model is an abstract thing, we always need some form of syntax to express the abstract logical model in a concrete form, that we can write down and then read.  So Date & Darwen created Tutorial D to make sure they had a syntax that they could use to precisely express their TTM model.

We tend to think about the abstract model in terms of the syntax because psychologically it's difficult not to.  But in the long run we need to learn to distinguish the two.

Now the question of tuples and attributes.  Here is an analogy of what I'm trying to get at.  When I think of a human being, I think of a creature consisting of a head, body, left arm, right arm, left leg and right leg.  I need the concepts of arms, legs, etc in order to understand the concept of a human being.  I don't mean that it’s possible to see a lone leg (left or right) walking down the street on its own, or a head rolling along on its own, or ... .  Arms and legs are necessary to understand human beings, but do not exist independently of human beings.

Likewise a relation consists of attributes and tuples, but I don’t expect attributes and tuples to appear ON THEIR OWN in a relational database.  Even if I were to use TTM model relations as part of a general purpose programming language, I don’t want attributes and tuples to appear ON THEIR OWN in that programming language.

When I agree with dandl, that’s all I’m getting at.  Of course the logical consequence is that all operators, etc, etc whose purpose is to support the existence of tuples INDEPENDENTLY OF relations need not appear ON THEIR OWN.

Since the concepts of attributes and tuples are integral to the concept of relations (at least TTM model relations) then the Tutorial D syntax used to express the TTM model MUST include the means to express attributes and tuples.  Such syntax is especially useful if you want to refer to some particular attribute or tuple in a relation, or to create a relation value from component attribute or tuple values.

Quote from AntC on July 1, 2021, 6:49 am

What dogged the previous discussion was a) the idea that avoiding a keyword TUPLE was thereby avoiding the concept or type of a tuple in a D; b) that storing the body of a relation in some form such that there was no contiguous patch of memory/disk representing a tuple was thereby avoiding there being something in the semantics of type tuple.

I hope my previous post explains why the CONCEPT of a tuple remains (because it's part of the concept of a relation) but a tuple TYPE as an independent entity can be dispensed with.  The keyword TUPLE is a part of the syntax; I have nothing to say about that.  Neither have I anything to say on physical implementation aspects such as a "contiguous patch of memory/disk".

Quote from AntC on July 1, 2021, 6:49 am

If you mean you don't want your D to have vars of type tuple, or support stand-alone expressions representing a tuple not inside a relation value -- well ok, but you haven't avoided "a 'mathematical sort' or category of data type".

You're right that I don't want my "D to have vars of type tuple, or support stand-alone expressions representing a tuple not inside a relation value".  But I have avoided a mathematical sort of a tuple type as a separate entity in the formal model.  The CONCEPT is already there as part of the concept of a relation, and hence part of a relation sort; which is why I don't want to duplicate it and build it up as a separate 'sort'.

Quote from AntC on July 1, 2021, 6:49 am

I can think of Chars, Booleans, Floats, Ints without having to think of arrays of those. The cell's type is orthogonal to the array structure.

Agreed.  The cell's type is also orthogonal to the relation structure.  A relational 'cell' can be any of any scalar or relational type (as long as it fits the type of the containing relational structure).  I don't understand what this has to do with the point I was trying to express.

Regarding coercion.
Having used both compiled and interpreted languages, I regard 'coercion' as the changing of a value's type.  For example, changing the type of a value from a tuple to a relation (which then has a cardinality of one) in order to insert it into a relvar, is a coercion.  It can be done by a compiler via static checking, or an interpreter via an explicit type change, or ... .  I don't care about the implementation method because I'm not concerned about implementation.  Compilers and interpreters are just part of the implementation.  My meaning of coercion may be different to yours, and maybe many other people's.  This all I meant.

Quote from Dave Voorhis on July 1, 2021, 2:59 pm

A relation of cardinality 1 is a wrapper around a tuple, by definition. So why not have just a tuple?

It's sometimes convenient to be able to do this:

OPERATOR thwokSpiffler(xfkj Merfle, pgl Zorg) RETURNS TUPLE {x INT, y INT, z INT} ...

When you're programming, does the wrapper make any difference ?  If so, what is it ?

I wonder if some of this is a matter of what programming styles we've learnt in the past.  I personally prefer something very general so that it's more flexible.  It means that (now or in maintenance) I can have OPERATOR thwokSpiffler return a relation value of zero, one, or more tuples, with much less worry about changes to the interface and whereOPERATOR thwokSpiffler is called.  But we're all different.

Would you find it useful to have an attribute type, values of which were a bag of values all of a given type ?

Quote from David Livingstone on July 1, 2021, 8:18 pm
Quote from Dave Voorhis on July 1, 2021, 2:59 pm

A relation of cardinality 1 is a wrapper around a tuple, by definition. So why not have just a tuple?

It's sometimes convenient to be able to do this:

OPERATOR thwokSpiffler(xfkj Merfle, pgl Zorg) RETURNS TUPLE {x INT, y INT, z INT} ...

When you're programming, does the wrapper make any difference ?  If so, what is it ?

I wonder if some of this is a matter of what programming styles we've learnt in the past.  I personally prefer something very general so that it's more flexible.  It means that (now or in maintenance) I can have OPERATOR thwokSpiffler return a relation value of zero, one, or more tuples, with much less worry about changes to the interface and whereOPERATOR thwokSpiffler is called.  But we're all different.

Would you find it useful to have an attribute type, values of which were a bag of values all of a given type ?

Returning a tuple restricts it to one of x, y, and z. Returning a relation allows zero to n tuples of x, y, and z.

The difference between the two is as significant as, say, the difference between a string and an integer, or the distinction between any other selection of incompatible types.

It's about using the right type to represent the solution, so that using the wrong type can be identified by the compiler as an error. Otherwise, we might as well use dynamic typing without type annotations. That's not flexibility, that's looseness. Flexibility isn't looseness. It's being able to change without loss of safety, generality, and reliability.

An uncaught bug is almost always costlier than changing the typeful interface that prevents a bug.

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 David Livingstone on July 1, 2021, 7:06 pm

Thank you for the responses to my posting.

Ok David, we're going to continue to disagree. I'll be brief, this horse is already well flogged.

Likewise a relation consists of attributes and tuples, but I don’t expect attributes and tuples to appear ON THEIR OWN in a relational database.  Even if I were to use TTM model relations as part of a general purpose programming language, I don’t want attributes and tuples to appear ON THEIR OWN in that programming language.

We're not talking about merely "in a relational database" but also in a fully featured programming language that manipulates values to/from a database as permanent storage of its manipulations. All modern programming languages support tuples appearing "ON THEIR OWN", as Dave points out.

The way tuples appear in other languages is unfortunate: ("S1", "P5", 50) (which is valid Haskell). Unfortunate because the elements are identified purely positionally; it is way too easy to confuse the positions (especially if they're of the same type). Many hours of debugging ensue. This is also valid Haskell (but needs a few declarations first): (SNo "S1", PNo "P5", Qty 50). But still that's positional-based; this is type-distinct and incomparable: (PNo "P5", Qty 50, SNo "S1")TTM-style tuples appearing "ON THEIR OWN" are in every way superior to Haskell tuples -- and I say that even if there's no database involved anywhere. They add to type safety; they aid flexibility; positional tuples add 'unnecessary complexity' (to borrow another nostrum from the industry) because I have to remember what each position means, the datatype doesn't say it on the tin.

So I would go further than TTM. I want attributes -- that is, name-value pairs -- to be first-class, to appear "ON THEIR OWN", not to be restricted to purely inside tuples. Haskell can do that today, Qty 50 is a valid standalone expression but it needs a declaration first.

When I agree with dandl, that’s all I’m getting at.  Of course the logical consequence is that all operators, etc, etc whose purpose is to support the existence of tuples INDEPENDENTLY OF relations need not appear ON THEIR OWN.

Since the concepts of attributes and tuples are integral to the concept of relations (at least TTM model relations) then the Tutorial D syntax used to express the TTM model MUST include the means to express attributes and tuples.  Such syntax is especially useful if you want to refer to some particular attribute or tuple in a relation, or to create a relation value from component attribute or tuple values.

The syntax I'd prefer for tuples/relations is for example {{SNo "S1", PNo "P5", Qty 50}, {PNo "P6", Qty 100, SNo "S7"}}, in which each of the elements between commas is valid standalone. I appreciate that in a teaching language like Tutorial D, it's wise to be more explicit with a selector/constructor.

Regarding coercion.
Having used both compiled and interpreted languages, I regard 'coercion' as the changing of a value's type.  For example, changing the type of a value from a tuple to a relation (which then has a cardinality of one) in order to insert it into a relvar, is a coercion.  It can be done by a compiler via static checking, or an interpreter via an explicit type change, or ... .  I don't care about the implementation method because I'm not concerned about implementation.  Compilers and interpreters are just part of the implementation.  My meaning of coercion may be different to yours, and maybe many other people's.  This all I meant.

"My meaning of [xxx] may be different to yours, and maybe other people's" comes straight from Humpty Dumpty.  "When I use a word," Humpty Dumpty said, in rather a scornful tone, "it means just what I choose it to mean, neither more nor less." Ok then don't expect anybody else to understand you. Perhaps when you use "tuple" or "relation" you mean something different? Where does it end?

I think you are just flagrantly wrong in your use of the term. You're trying to get the bad vibes of "coercion" whilst abusing its meaning. Wrapping a value of one type in a selector/constructor to produce a value of a different type is not coercion, it's ... wrapping.

If the operator/command that inserts a tuple into a relvar expects an operand of type tuple, no wrapping is needed. If it expects an operand of type relation (because for example it can thereby insert several tuples), it's a type error to supply a tuple. I wouldn't expect the compiler to wrap it automatically in a REL constructor. If you want to insert a lot of single tuples, the language should support a user-defined operator for that. And I note D&D are averse to implicit type-changing -- quite right too.

You seem to not have much exposure to programming languages or to programming language theory. Which languages have you used other than RAQUEL?

Quote from Dave Voorhis on July 1, 2021, 2:59 pm
Quote from dandl on July 1, 2021, 1:44 pm

You'll have to provide an example if you want to make that claim. I know of none.

Tuple values have always been second class in TTM. They are defined in passing in Pre 9 and as a note to Pre 18, but they read to me almost as an afterthought, something added just to fill in some blanks. As far as I can tell, whatever you can do with a tuple you can do equally well with a relation of cardinality 1. But I may have missed something.

A relation of cardinality 1 is a wrapper around a tuple, by definition. So why not have just a tuple?

Why introduce a whole new type with all its attendant baggage (variables, values, operators, etc) when you already have everything you need in a relation of cardinality 1?

It's sometimes convenient to be able to do this:

OPERATOR thwokSpiffler(xfkj Merfle, pgl Zorg) RETURNS TUPLE {x INT, y INT, z INT} ...

Is it necessary?

No, you could define a type with a possrep having three elements, but tuples have an ad-hoc convenience that defining a new type often doesn't.

Yes, it is useful to return multiple values from a function, but you don't need a TTM TUPLE type to achieve that. Lots of languages have ways to do that.

Don't you sometimes find tuples convenient in C# and Python?

They're not necessary there either, but they're handy.

Indeed, they make less sense in C# and Python than a D, given a D has relations composed of tuples (and a heading.) That makes tuples unavoidably semantically present, which means it's hard to argue a case that they should only appear wrapped in relations when they're obviously handy outside of relations too.

You are conflating the idea of having 'some kind of tuple thing' with 'a TUPLE type with HEADING and associated relational operators as per TTM'. Yes, tuples are handy; no, TUPLE as per TTM is unnecessary.

Case closed. TUPLE as per TTM is not required.

Andl - A New Database Language - andl.org
Quote from dandl on July 2, 2021, 6:23 am
Quote from Dave Voorhis on July 1, 2021, 2:59 pm
Quote from dandl on July 1, 2021, 1:44 pm

You'll have to provide an example if you want to make that claim. I know of none.

Tuple values have always been second class in TTM. They are defined in passing in Pre 9 and as a note to Pre 18, but they read to me almost as an afterthought, something added just to fill in some blanks. As far as I can tell, whatever you can do with a tuple you can do equally well with a relation of cardinality 1. But I may have missed something.

A relation of cardinality 1 is a wrapper around a tuple, by definition. So why not have just a tuple?

Why introduce a whole new type with all its attendant baggage (variables, values, operators, etc) when you already have everything you need in a relation of cardinality 1?

It's sometimes convenient to be able to do this:

OPERATOR thwokSpiffler(xfkj Merfle, pgl Zorg) RETURNS TUPLE {x INT, y INT, z INT} ...

Is it necessary?

No, you could define a type with a possrep having three elements, but tuples have an ad-hoc convenience that defining a new type often doesn't.

Yes, it is useful to return multiple values from a function, but you don't need a TTM TUPLE type to achieve that. Lots of languages have ways to do that.

Don't you sometimes find tuples convenient in C# and Python?

They're not necessary there either, but they're handy.

Indeed, they make less sense in C# and Python than a D, given a D has relations composed of tuples (and a heading.) That makes tuples unavoidably semantically present, which means it's hard to argue a case that they should only appear wrapped in relations when they're obviously handy outside of relations too.

You are conflating the idea of having 'some kind of tuple thing' with 'a TUPLE type with HEADING and associated relational operators as per TTM'. Yes, tuples are handy; no, TUPLE as per TTM is unnecessary.

Case closed. TUPLE as per TTM is not required.

Both WHILE and DO loops aren't required in Tutorial D either, but they're nice to have. Are RM Pre 6, 12, 20, and 22b strictly necessary?

No -- that's already been agreed in this thread -- but given that tuple semantics are unavoidable (per RM Pre 10b, and any reasonable relational model, etc), it would be strange not to support and require first-class tuples, particularly as TTM isn't an exercise in defining the strictly minimal set of constructs sufficient to specify a relational programming language.

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 July 1, 2021, 9:04 pm
Returning a tuple restricts it to one of x, y, and z. Returning a relation allows zero to n tuples of x, y, and z.
The difference between the two is as significant as, say, the difference between a string and an integer, or the distinction between any other selection of incompatible types.

I agree with you.  What I omitted to say was that I would expect to be able to put an integrity constraint on the output relation value that enforced a cardinality of one, and hence corresponded to a tuple.  Mea Culpa.

You can place such constraints in RAQUEL, but now I think about it, I don't recall it in Tutorial D.

The ability to place cardinality constraints is an example of the flexibility I was trying (badly) to refer to.  Two examples :

  1.  If a distribution company has 17 warehouses (to take a random number), such that a relvar containing data about their warehouses must have exactly 17 tuples, then you can place a cardinality constraint on it to achieve that.
  2. If you don't want any data put into a relvar that is created as part of a standard setup procedure until some specific event has occurred (say some kind of security check), then you can set its cardinality to be zero.  In processing the specific event, you can remove the constraint or set it to the desired number.
Quote from David Livingstone on July 2, 2021, 10:39 am
Quote from Dave Voorhis on July 1, 2021, 9:04 pm
Returning a tuple restricts it to one of x, y, and z. Returning a relation allows zero to n tuples of x, y, and z.
The difference between the two is as significant as, say, the difference between a string and an integer, or the distinction between any other selection of incompatible types.

I agree with you.  What I omitted to say was that I would expect to be able to put an integrity constraint on the output relation value that enforced a cardinality of one, and hence corresponded to a tuple.  Mea Culpa.

You can place such constraints in RAQUEL, but now I think about it, I don't recall it in Tutorial D.

The ability to place cardinality constraints is an example of the flexibility I was trying (badly) to refer to.  Two examples :

  1.  If a distribution company has 17 warehouses (to take a random number), such that a relvar containing data about their warehouses must have exactly 17 tuples, then you can place a cardinality constraint on it to achieve that.
  2. If you don't want any data put into a relvar that is created as part of a standard setup procedure until some specific event has occurred (say some kind of security check), then you can set its cardinality to be zero.  In processing the specific event, you can remove the constraint or set it to the desired number.

You can declare a possrep TYPE and define arbitrary constraints on cardinality or whatever in Tutorial D, but there is nothing to say (e.g.,) OPERATOR blah RETURNS RELATION {x INT, y INT} CONSTRAINT COUNT() = 17.

But if you could say OPERATOR blah RETURNS RELATION {x INT, y INT} CONSTRAINT COUNT() = 1, then I'd rather say OPERATOR blah RETURNS TUPLE {x INT, y INT}.

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 July 1, 2021, 10:18 pm
Ok David, we're going to continue to disagree.
So be it.
Quote from AntC on July 1, 2021, 10:18 pm

We're not talking about merely "in a relational database" but also in a fully featured programming language that manipulates values to/from a database as permanent storage of its manipulations. All modern programming languages support tuples appearing "ON THEIR OWN", as Dave points out.

The way tuples appear in other languages is unfortunate: ("S1", "P5", 50) (which is valid Haskell). Unfortunate because the elements are identified purely positionally; it is way too easy to confuse the positions (especially if they're of the same type).

I appreciate that you might want something else added to fit in with Haskell.  Given all the different programming languages used these days, each of them might want something else (specific to them) added to fit in with them.  This is to do with what is/used to be called the 'Impedance Mismatch' between a TTM-conforming relational language and another programming language, one used to write an application that uses data from a relational DB whose DBMS uses the TTM-conforming language.

(When I referred to using TTM model relations as part of a general purpose programming language, and not wanting attributes and tuples to appear ON THEIR OWN in that language, I meant a general purpose programming language that conforms to TTM.  Sorry if I didn't make that clear).

Given that there are many different programming languages used these days, might it not be a better strategy to have a relationally-oriented supplement for each different language, that could be plugged into Tutorial D (or other TTM-conforming languages) that provides all the extras that you want - e.g. TUPLE TYPE, name-value pairs, etc - for that language, so as to smooth out the 'Impedance Mismatch' between the 2 languages ?  Or perhaps start with one 'basic' supplement that might provide most of the smoothing for most commonly used languages ?

Both dandl and I recognise that TUPLE TYPES already exist in TTM.  We'd just like them removed to simplify the model.  But the supplement would allow you to keep them, were they ever to be removed.

Quote from AntC on July 1, 2021, 10:18 pm
"My meaning of [xxx] may be different to yours, and maybe other people's" comes straight from Humpty Dumpty.

Actually it comes straight from computing.  The computing profession is notorious for not coming to an agreement on standard terminology, and is a contrast to many of the well-established sciences and engineering subjects, who once a new topic is researched, tend towards standardised phraseology as an aid to communication.  (If you write a computing paper for publication, you typically have to define your terms to ensure the reader knows what you mean in the paper by word 'XXX', even when 'XXX' is a well-known term).

So I tried to explain what I meant by coercion, which for me is a much more general concept than what typically is the case in specific programming languages.

PreviousPage 6 of 9Next