The Forum for Discussion about The Third Manifesto and Related Matters

Please or Register to create posts and topics.

Tuples FTW

Quote from Hugh on April 28, 2021, 2:32 pm
Quote from Hugh on April 28, 2021, 10:36 am
Quote from tobega on April 28, 2021, 6:47 am

On the subject of type system for a language capable of hosting a D (and also for Tailspin, of course), we have observed that Tuples must be structurally typed, i.e. the attributes they contain define them as the product type of those attributes.

As a counterpoint to a previous thread here, I propose that Tuples be THE way to create product types.

The latest insight (or train-wreck) that I had, is that we should let attributes define types, i.e. instead of saying that an attribute has a type, we say that an attribute is a type. I think this fits very nicely with the natural join and that we take the position that things with the same name are the same kind of things. It also fits in with a good practice to create specific types for specific things, even if in Java it is a bit of a pain to e.g. create a SupplierName class that simply wraps a String.

So we would declare that there is a type called PNAME of the base type string, and the type called SNAME of the base type string, and you just use them as attributes in the Tuples, the type and the attribute have the same name.

Obviously you cannot assign an SNAME value to a PNAME attribute without casting it. But you could e.g. have a COMPANY_NAME and have SNAME be of the type COMPANY_NAME, which would enable assigning between the two.

So, comments? Good idea? Insane idea?

I've seen other replies.  It doesn't look like a good idea to me but in any case clarification is needed.  Please give examples of type definitions for, e.g., SNAME and PNAME, preferably using TD-like syntax.  I assume you imagine a relation type definition to be like TD's but with just attribute type names as heading components: REL{SNO, SNAME, CITY

What do you think a value of an attribute type looks like.   Please give a literal denoting the supplier name Smith.

What are the implications for the relational RENAME operator?

Hugh

P.S.  Perhaps more appropriate, what about EXTEND?  In particular, I have a query that involves extension with concatenation of FirstName and LastName (with a blank in between).  How is that done?

Answering once for both of your posts.

I wouldn't necessarily change anything from the TD syntax, if that is the syntax you want, so

TUPLE { S# S#, SNAME NAME, STATUS INTEGER, CITY CHAR }

TUPLE { S# S#('S1'), SNAME NAME('Smith'), STATUS 20, CITY 'London' }

But what would happen is that we would now automatically also have the types SNAME, STATUS and CITY defined, and the "real" type of the CITY attribute would be CITY, but it could be assigned values of the representation type CHAR.

I believe I answered the RENAME case in my reply to Darren.

As for EXTEND, I suppose that would work similarly in that you would have to explicitly assert the conversion to appropriate types. So FirstName is what? CHAR? And LastName might also be CHAR. So lets look at TD syntax:

EXTEND a ADD (CHAR(FirstName)+' '+CHAR(LastName) AS FullName)

If FullName has not been previously defined, there will now be a type "FullName CHAR", and any attribute FullName can be assumed to be of type FullName, without needing specification. But it wouldn't necessarily hurt to respecify "FullName CHAR". However, trying to specify e.g. "FullName INT" would not be allowed anywhere, you would have to forego that option.

Quote from AntC on April 28, 2021, 11:50 am
Quote from tobega on April 28, 2021, 6:47 am

On the subject of type system for a language capable of hosting a D (and also for Tailspin, of course), we have observed that Tuples must be structurally typed, i.e. the attributes they contain define them as the product type of those attributes.

As a counterpoint to a previous thread here, I propose that Tuples be THE way to create product types.

Careful: in most languages, 'product type' means an ordered product. Type (Int, Bool) is distinct from (Bool, Int). So do you mean TUPLE{ SNAME 'Acme', PNAME 'Grommet'} is type distinct from TUPLE{ PNAME 'Grommet', SNAME 'Acme'}?

No, when you have names you don't have to succumb to the stupidities inherent in relying on order. 2*N is the same product as N*2

The latest insight (or train-wreck) that I had, is that we should let attributes define types, i.e. instead of saying that an attribute has a type, we say that an attribute is a type. I think this fits very nicely with the natural join and that we take the position that things with the same name are the same kind of things. It also fits in with a good practice to create specific types for specific things, even if in Java it is a bit of a pain to e.g. create a SupplierName class that simply wraps a String.

So we would declare that there is a type called PNAME of the base type string, and the type called SNAME of the base type string, and you just use them as attributes in the Tuples, the type and the attribute have the same name.

No wrong. Because we have to cope with ad-hoc attribute naming: type X Int distinct from X String. Furthermore we don't want bare String or Int being allowed as types of attributes. We always want there to be a wrapper; and the wrapper to wrap a single 'payload' type.

Take a look at Haskell (or most Functional Languages') 'datatype renamings' section 4.2.3.

newtype X a = X a  -- where a (parametric) denotes some arbitrary type

In a nominal typing system, type name X Int is distinct from type Int. The newtype construct says they are to share the same PhysRep.

Sure, you just have to give up ad-hoc attribute naming and start using as meaningful names for the attributes as you do for the types (i.e. the same name)

Obviously you cannot assign an SNAME value to a PNAME attribute without casting it.

Sure, because type SNAME String is distinct from PNAME String. But 'casting' is not the appropriate mechanism here: unwrap the string from one then re-wrap it into the other. In Functional languages that's achieved via 'pattern matching'. And because the compiler knows they're newtypes and therefore share the same PhysRep, that's a no-op.  Tutorial D has SNAME FROM ... -- in which presumably unwrap/rewrap is computationally more clunky.

Fair enough.

But you could e.g. have a COMPANY_NAME and have SNAME be of the type COMPANY_NAME, which would enable assigning between the two.

No this is nominal typing: if two types are different named, they are different types, you can't directly assign between them. Perhaps you mean SNAME String is an alias aka shorthand for COMPANY_NAME String (or vice versa)? (See section 4.2.2, type decl.) [Note **]

Nominal typing for attributes, structural typing for tuples.

So, comments? Good idea? Insane idea?

I've already built a D-alike extension to Haskell using this idea. But Haskell treats its tuples positionally. So it needed ugly generics to treat these two tuples as being under a type-equivalence relationship. (Note I didn't say 'same type'.)

sp = tuple_union (PName 'Grommet', SName 'Acme', Qty 50) (SName 'Jones', Qty 100, PName 'Grommet')
sp = tuple_union (PName 'Grommet', SName 'Acme', Qty 50) (SName 'Jones', Qty 100, PName 'Grommet')
sp = tuple_union (PName 'Grommet', SName 'Acme', Qty 50) (SName 'Jones', Qty 100, PName 'Grommet')

In which tuple_union is a function that takes two (positional) Haskell tuples, and returns (an equivalent of) a TTM relation value.

Note ** You could use the type alias idea like this:

type COMPANY_NAME = SName String
type COMPANY_NAME = SName String
type COMPANY_NAME = SName String

That declares a single lexeme COMPANY_NAME as shorthand for a wrapped type (two lexemes). And everywhere your code uses the single lexeme, it's immediately expanded to the two-lexeme form.

Ah, cool. In Julia there is also annoying remnants of the order of attributes even when using a named tuple, damned inconvenient.

Quote from tobega on April 28, 2021, 6:47 am

On the subject of type system for a language capable of hosting a D (and also for Tailspin, of course), we have observed that Tuples must be structurally typed, i.e. the attributes they contain define them as the product type of those attributes.

As a counterpoint to a previous thread here, I propose that Tuples be THE way to create product types.

The latest insight (or train-wreck) that I had, is that we should let attributes define types, i.e. instead of saying that an attribute has a type, we say that an attribute is a type. I think this fits very nicely with the natural join and that we take the position that things with the same name are the same kind of things. It also fits in with a good practice to create specific types for specific things, even if in Java it is a bit of a pain to e.g. create a SupplierName class that simply wraps a String.

So we would declare that there is a type called PNAME of the base type string, and the type called SNAME of the base type string, and you just use them as attributes in the Tuples, the type and the attribute have the same name.

Obviously you cannot assign an SNAME value to a PNAME attribute without casting it. But you could e.g. have a COMPANY_NAME and have SNAME be of the type COMPANY_NAME, which would enable assigning between the two.

So, comments? Good idea? Insane idea?

Codd presumed tuples that are conjunctions of binary products of given factors. A given product and factor pair are the dual contents of any interpretation an application chooses. Universal interpretations can correspond to what you might call Hasa predicates, existential interpretations correspond to Isa predicates, aka about the relation that has a tuple or the tuple that is a member of a relation.

But in the relational model, applications have no way to choose the recorded interpretation of a tuple in isolation.

Questions about the difference between Hasa and Isa predicates are merely questions about the difference between applications. When they are posed to coder clubs the resulting talk is likely to devolve into endless circular contemplation of pointless problems like how to represent representations. Languages defined only on propositional logic and application objects are not a sufficient basis to answer such questions or to define relational database storage semantics. They are logically incomplete for the purpose.

For example, in relational logic the so-called deletion of a tuple from the suppliers relation involves more relations than just the suppliers relation and a singleton subset of it. Codd's point was that application coders don't need to know this if they use a system that in effect recognizes it. They are actually happier and more efficient when they don't know it. They don't even need to know when they are using a language defined on the restricted logic that Codd specified which requires union compatibe and relative complement operations and expressible objects, not just named objects.

When system designers think like application coders big insoluble problems come up because coders don't need to know what to count. For example, designers need to count the expressible relations, not just the named ones. Because they usually don't, suddenly it will happen that somebody thinks negating London suppliers means they could just as well be made into Paris suppliers. Inability to count results in such chaotic thinking and systems that allow expressions which are undecidable and logically unprovable results. When the expressible relations are logically independent sets it's possible to evaluate results propositionally.

Quote from p c on April 28, 2021, 5:13 pm
Quote from tobega on April 28, 2021, 6:47 am

On the subject of type system for a language capable of hosting a D (and also for Tailspin, of course), we have observed that Tuples must be structurally typed, i.e. the attributes they contain define them as the product type of those attributes.

As a counterpoint to a previous thread here, I propose that Tuples be THE way to create product types.

The latest insight (or train-wreck) that I had, is that we should let attributes define types, i.e. instead of saying that an attribute has a type, we say that an attribute is a type. I think this fits very nicely with the natural join and that we take the position that things with the same name are the same kind of things. It also fits in with a good practice to create specific types for specific things, even if in Java it is a bit of a pain to e.g. create a SupplierName class that simply wraps a String.

So we would declare that there is a type called PNAME of the base type string, and the type called SNAME of the base type string, and you just use them as attributes in the Tuples, the type and the attribute have the same name.

Obviously you cannot assign an SNAME value to a PNAME attribute without casting it. But you could e.g. have a COMPANY_NAME and have SNAME be of the type COMPANY_NAME, which would enable assigning between the two.

So, comments? Good idea? Insane idea?

Codd presumed tuples that are conjunctions of binary products of given factors. A given product and factor pair are the dual contents of any interpretation an application chooses. Universal interpretations can correspond to what you might call Hasa predicates, existential interpretations correspond to Isa predicates, aka about the relation that has a tuple or the tuple that is a member of a relation.

But in the relational model, applications have no way to choose the recorded interpretation of an tuple in isolation.

Questions about the difference between Hasa and Isa predicates are merely questions about the difference between applications. When they are posed to coder clubs the resulting talk is likely to devolve into endless circular contemplation of pointless problems like how to represent representations. Languages defined only on propositional logic and application objects are not a sufficient basis to answer such questions or to define relational database storage semantics. They are logically incomplete for the purpose.

For example, in relational logic the so-called deletion of a tuple from the suppliers relation in relational logic involves more relations than just the suppliers relation and a singleton subset of it. Codd's point was that application coders don't need to know this if they use a system that in effect recognizes it. They are actually happier and more efficient when they don't know it. They don't even need to know when they are using a language defined on the restricted logic that Codd specified which requires union compatibe and relative complement operations and expressible objects, not just named objects.

When system designers think like application coders big insoluble problems come up because coders don't need to know what to count. For example, designers need to count the expressible relations, not just the named ones. Because they usually don't, suddenly it will happen that somebody thinks negating London suppliers means they could just as well be made into Paris suppliers. Inability to count results in such chaotic thinking and systems that allow expressions which are undecidable and logically unprovable results. When the expressible relations are logically independent sets it's possible to evaluate results propositionally.

Sorry, I have no clue what you are saying or how it relates to my proposal. Can you rephrase it?

Quote from tobega on April 28, 2021, 5:23 pm
Quote from p c on April 28, 2021, 5:13 pm
Quote from tobega on April 28, 2021, 6:47 am

On the subject of type system for a language capable of hosting a D (and also for Tailspin, of course), we have observed that Tuples must be structurally typed, i.e. the attributes they contain define them as the product type of those attributes.

As a counterpoint to a previous thread here, I propose that Tuples be THE way to create product types.

The latest insight (or train-wreck) that I had, is that we should let attributes define types, i.e. instead of saying that an attribute has a type, we say that an attribute is a type. I think this fits very nicely with the natural join and that we take the position that things with the same name are the same kind of things. It also fits in with a good practice to create specific types for specific things, even if in Java it is a bit of a pain to e.g. create a SupplierName class that simply wraps a String.

So we would declare that there is a type called PNAME of the base type string, and the type called SNAME of the base type string, and you just use them as attributes in the Tuples, the type and the attribute have the same name.

Obviously you cannot assign an SNAME value to a PNAME attribute without casting it. But you could e.g. have a COMPANY_NAME and have SNAME be of the type COMPANY_NAME, which would enable assigning between the two.

So, comments? Good idea? Insane idea?

Codd presumed tuples that are conjunctions of binary products of given factors. A given product and factor pair are the dual contents of any interpretation an application chooses. Universal interpretations can correspond to what you might call Hasa predicates, existential interpretations correspond to Isa predicates, aka about the relation that has a tuple or the tuple that is a member of a relation.

But in the relational model, applications have no way to choose the recorded interpretation of an tuple in isolation.

Questions about the difference between Hasa and Isa predicates are merely questions about the difference between applications. When they are posed to coder clubs the resulting talk is likely to devolve into endless circular contemplation of pointless problems like how to represent representations. Languages defined only on propositional logic and application objects are not a sufficient basis to answer such questions or to define relational database storage semantics. They are logically incomplete for the purpose.

For example, in relational logic the so-called deletion of a tuple from the suppliers relation in relational logic involves more relations than just the suppliers relation and a singleton subset of it. Codd's point was that application coders don't need to know this if they use a system that in effect recognizes it. They are actually happier and more efficient when they don't know it. They don't even need to know when they are using a language defined on the restricted logic that Codd specified which requires union compatibe and relative complement operations and expressible objects, not just named objects.

When system designers think like application coders big insoluble problems come up because coders don't need to know what to count. For example, designers need to count the expressible relations, not just the named ones. Because they usually don't, suddenly it will happen that somebody thinks negating London suppliers means they could just as well be made into Paris suppliers. Inability to count results in such chaotic thinking and systems that allow expressions which are undecidable and logically unprovable results. When the expressible relations are logically independent sets it's possible to evaluate results propositionally.

Sorry, I have no clue what you are saying or how it relates to my proposal. Can you rephrase it?

P C appears to be a random content generator, except rather than producing stochastic poetry or fake scientific papers, it emits TTM forum posts loosely based on the relational model. It occasionally generates something achingly close to making sense, but then inevitably veers away, leaving only a tantalising hint of meaning without actually delivering any.

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 April 28, 2021, 2:51 pm
Quote from Hugh on April 28, 2021, 2:32 pm
Quote from Hugh on April 28, 2021, 10:36 am
Quote from tobega on April 28, 2021, 6:47 am

On the subject of type system for a language capable of hosting a D (and also for Tailspin, of course), we have observed that Tuples must be structurally typed, i.e. the attributes they contain define them as the product type of those attributes.

As a counterpoint to a previous thread here, I propose that Tuples be THE way to create product types.

The latest insight (or train-wreck) that I had, is that we should let attributes define types, i.e. instead of saying that an attribute has a type, we say that an attribute is a type. I think this fits very nicely with the natural join and that we take the position that things with the same name are the same kind of things. It also fits in with a good practice to create specific types for specific things, even if in Java it is a bit of a pain to e.g. create a SupplierName class that simply wraps a String.

So we would declare that there is a type called PNAME of the base type string, and the type called SNAME of the base type string, and you just use them as attributes in the Tuples, the type and the attribute have the same name.

Obviously you cannot assign an SNAME value to a PNAME attribute without casting it. But you could e.g. have a COMPANY_NAME and have SNAME be of the type COMPANY_NAME, which would enable assigning between the two.

So, comments? Good idea? Insane idea?

I've seen other replies.  It doesn't look like a good idea to me but in any case clarification is needed.  Please give examples of type definitions for, e.g., SNAME and PNAME, preferably using TD-like syntax.  I assume you imagine a relation type definition to be like TD's but with just attribute type names as heading components: REL{SNO, SNAME, CITY

What do you think a value of an attribute type looks like.   Please give a literal denoting the supplier name Smith.

What are the implications for the relational RENAME operator?

Hugh

P.S.  Perhaps more appropriate, what about EXTEND?  In particular, I have a query that involves extension with concatenation of FirstName and LastName (with a blank in between).  How is that done?

Assume:

TYPE FName POSSREP {Name CHAR};
TYPE LName POSSREP {Name CHAR};

Let Users be a relvar with attributes FirstName FName and LastName LName, then:

EXTEND Users: {FullName := THE_Name(FirstName) || ' ' || THE_Name(LastName)}

 

But FName and LName aren't "attribute types" as I (mis?)understood to be Tobega's proposal.  If your types are what Tobega meant, then I withdraw.  Personally I would normally bother with types like that but what you have written is unobjectionable.

Hugh

Hugh

Coauthor of The Third Manifesto and related books.
Quote from tobega on April 28, 2021, 3:25 pm
Quote from Hugh on April 28, 2021, 2:32 pm
Quote from Hugh on April 28, 2021, 10:36 am
Quote from tobega on April 28, 2021, 6:47 am

On the subject of type system for a language capable of hosting a D (and also for Tailspin, of course), we have observed that Tuples must be structurally typed, i.e. the attributes they contain define them as the product type of those attributes.

As a counterpoint to a previous thread here, I propose that Tuples be THE way to create product types.

The latest insight (or train-wreck) that I had, is that we should let attributes define types, i.e. instead of saying that an attribute has a type, we say that an attribute is a type. I think this fits very nicely with the natural join and that we take the position that things with the same name are the same kind of things. It also fits in with a good practice to create specific types for specific things, even if in Java it is a bit of a pain to e.g. create a SupplierName class that simply wraps a String.

So we would declare that there is a type called PNAME of the base type string, and the type called SNAME of the base type string, and you just use them as attributes in the Tuples, the type and the attribute have the same name.

Obviously you cannot assign an SNAME value to a PNAME attribute without casting it. But you could e.g. have a COMPANY_NAME and have SNAME be of the type COMPANY_NAME, which would enable assigning between the two.

So, comments? Good idea? Insane idea?

I've seen other replies.  It doesn't look like a good idea to me but in any case clarification is needed.  Please give examples of type definitions for, e.g., SNAME and PNAME, preferably using TD-like syntax.  I assume you imagine a relation type definition to be like TD's but with just attribute type names as heading components: REL{SNO, SNAME, CITY

What do you think a value of an attribute type looks like.   Please give a literal denoting the supplier name Smith.

What are the implications for the relational RENAME operator?

Hugh

P.S.  Perhaps more appropriate, what about EXTEND?  In particular, I have a query that involves extension with concatenation of FirstName and LastName (with a blank in between).  How is that done?

Answering once for both of your posts.

I wouldn't necessarily change anything from the TD syntax, if that is the syntax you want, so

TUPLE { S# S#, SNAME NAME, STATUS INTEGER, CITY CHAR }
TUPLE { S# S#('S1'), SNAME NAME('Smith'), STATUS 20, CITY 'London' }
TUPLE { S# S#, SNAME NAME, STATUS INTEGER, CITY CHAR } TUPLE { S# S#('S1'), SNAME NAME('Smith'), STATUS 20, CITY 'London' }
TUPLE { S# S#, SNAME NAME, STATUS INTEGER, CITY CHAR }

TUPLE { S# S#('S1'), SNAME NAME('Smith'), STATUS 20, CITY 'London' }

But what would happen is that we would now automatically also have the types SNAME, STATUS and CITY defined, and the "real" type of the CITY attribute would be CITY, but it could be assigned values of the representation type CHAR.

I believe I answered the RENAME case in my reply to Darren.

As for EXTEND, I suppose that would work similarly in that you would have to explicitly assert the conversion to appropriate types. So FirstName is what? CHAR? And LastName might also be CHAR. So lets look at TD syntax:

EXTEND a ADD (CHAR(FirstName)+' '+CHAR(LastName) AS FullName)
EXTEND a ADD (CHAR(FirstName)+' '+CHAR(LastName) AS FullName)
EXTEND a ADD (CHAR(FirstName)+' '+CHAR(LastName) AS FullName)

If FullName has not been previously defined, there will now be a type "FullName CHAR", and any attribute FullName can be assumed to be of type FullName, without needing specification. But it wouldn't necessarily hurt to respecify "FullName CHAR". However, trying to specify e.g. "FullName INT" would not be allowed anywhere, you would have to forego that option.

Oh, I didn't see this one until after I had responded to Dave Voorhis.  So I didn't misunderstand but you have now clarified.  The question now concerns the scope of this defined-on-the-fly type Fullname.  It has to be local to the expression in which it is defined, otherwise I would object strongly.  And it is is local to the expression, I can't see much point.

Hugh

Coauthor of The Third Manifesto and related books.
Quote from Hugh on April 29, 2021, 3:01 pm
Quote from Dave Voorhis on April 28, 2021, 2:51 pm
Quote from Hugh on April 28, 2021, 2:32 pm
Quote from Hugh on April 28, 2021, 10:36 am
Quote from tobega on April 28, 2021, 6:47 am

On the subject of type system for a language capable of hosting a D (and also for Tailspin, of course), we have observed that Tuples must be structurally typed, i.e. the attributes they contain define them as the product type of those attributes.

As a counterpoint to a previous thread here, I propose that Tuples be THE way to create product types.

The latest insight (or train-wreck) that I had, is that we should let attributes define types, i.e. instead of saying that an attribute has a type, we say that an attribute is a type. I think this fits very nicely with the natural join and that we take the position that things with the same name are the same kind of things. It also fits in with a good practice to create specific types for specific things, even if in Java it is a bit of a pain to e.g. create a SupplierName class that simply wraps a String.

So we would declare that there is a type called PNAME of the base type string, and the type called SNAME of the base type string, and you just use them as attributes in the Tuples, the type and the attribute have the same name.

Obviously you cannot assign an SNAME value to a PNAME attribute without casting it. But you could e.g. have a COMPANY_NAME and have SNAME be of the type COMPANY_NAME, which would enable assigning between the two.

So, comments? Good idea? Insane idea?

I've seen other replies.  It doesn't look like a good idea to me but in any case clarification is needed.  Please give examples of type definitions for, e.g., SNAME and PNAME, preferably using TD-like syntax.  I assume you imagine a relation type definition to be like TD's but with just attribute type names as heading components: REL{SNO, SNAME, CITY

What do you think a value of an attribute type looks like.   Please give a literal denoting the supplier name Smith.

What are the implications for the relational RENAME operator?

Hugh

P.S.  Perhaps more appropriate, what about EXTEND?  In particular, I have a query that involves extension with concatenation of FirstName and LastName (with a blank in between).  How is that done?

Assume:

TYPE FName POSSREP {Name CHAR};
TYPE LName POSSREP {Name CHAR};

Let Users be a relvar with attributes FirstName FName and LastName LName, then:

EXTEND Users: {FullName := THE_Name(FirstName) || ' ' || THE_Name(LastName)}

 

But FName and LName aren't "attribute types" as I (mis?)understood to be Tobega's proposal.  If your types are what Tobega meant, then I withdraw.  Personally I would normally bother with types like that but what you have written is unobjectionable.

Hugh

Unless I'm misunderstanding Tobega's proposal, my types are essentially what would be automatically created, though local to the expression in which they're used.

Quote from Hugh on April 29, 2021, 3:06 pm
Quote from tobega on April 28, 2021, 3:25 pm
Quote from Hugh on April 28, 2021, 2:32 pm
Quote from Hugh on April 28, 2021, 10:36 am
Quote from tobega on April 28, 2021, 6:47 am

On the subject of type system for a language capable of hosting a D (and also for Tailspin, of course), we have observed that Tuples must be structurally typed, i.e. the attributes they contain define them as the product type of those attributes.

As a counterpoint to a previous thread here, I propose that Tuples be THE way to create product types.

The latest insight (or train-wreck) that I had, is that we should let attributes define types, i.e. instead of saying that an attribute has a type, we say that an attribute is a type. I think this fits very nicely with the natural join and that we take the position that things with the same name are the same kind of things. It also fits in with a good practice to create specific types for specific things, even if in Java it is a bit of a pain to e.g. create a SupplierName class that simply wraps a String.

So we would declare that there is a type called PNAME of the base type string, and the type called SNAME of the base type string, and you just use them as attributes in the Tuples, the type and the attribute have the same name.

Obviously you cannot assign an SNAME value to a PNAME attribute without casting it. But you could e.g. have a COMPANY_NAME and have SNAME be of the type COMPANY_NAME, which would enable assigning between the two.

So, comments? Good idea? Insane idea?

I've seen other replies.  It doesn't look like a good idea to me but in any case clarification is needed.  Please give examples of type definitions for, e.g., SNAME and PNAME, preferably using TD-like syntax.  I assume you imagine a relation type definition to be like TD's but with just attribute type names as heading components: REL{SNO, SNAME, CITY

What do you think a value of an attribute type looks like.   Please give a literal denoting the supplier name Smith.

What are the implications for the relational RENAME operator?

Hugh

P.S.  Perhaps more appropriate, what about EXTEND?  In particular, I have a query that involves extension with concatenation of FirstName and LastName (with a blank in between).  How is that done?

Answering once for both of your posts.

I wouldn't necessarily change anything from the TD syntax, if that is the syntax you want, so

TUPLE { S# S#, SNAME NAME, STATUS INTEGER, CITY CHAR }
TUPLE { S# S#('S1'), SNAME NAME('Smith'), STATUS 20, CITY 'London' }
TUPLE { S# S#, SNAME NAME, STATUS INTEGER, CITY CHAR } TUPLE { S# S#('S1'), SNAME NAME('Smith'), STATUS 20, CITY 'London' }
TUPLE { S# S#, SNAME NAME, STATUS INTEGER, CITY CHAR }

TUPLE { S# S#('S1'), SNAME NAME('Smith'), STATUS 20, CITY 'London' }

But what would happen is that we would now automatically also have the types SNAME, STATUS and CITY defined, and the "real" type of the CITY attribute would be CITY, but it could be assigned values of the representation type CHAR.

I believe I answered the RENAME case in my reply to Darren.

As for EXTEND, I suppose that would work similarly in that you would have to explicitly assert the conversion to appropriate types. So FirstName is what? CHAR? And LastName might also be CHAR. So lets look at TD syntax:

EXTEND a ADD (CHAR(FirstName)+' '+CHAR(LastName) AS FullName)
EXTEND a ADD (CHAR(FirstName)+' '+CHAR(LastName) AS FullName)
EXTEND a ADD (CHAR(FirstName)+' '+CHAR(LastName) AS FullName)

If FullName has not been previously defined, there will now be a type "FullName CHAR", and any attribute FullName can be assumed to be of type FullName, without needing specification. But it wouldn't necessarily hurt to respecify "FullName CHAR". However, trying to specify e.g. "FullName INT" would not be allowed anywhere, you would have to forego that option.

Oh, I didn't see this one until after I had responded to Dave Voorhis.  So I didn't misunderstand but you have now clarified.  The question now concerns the scope of this defined-on-the-fly type Fullname.  It has to be local to the expression in which it is defined, otherwise I would object strongly.  And it is is local to the expression, I can't see much point.

Hugh

The point, as I understand it, is to automagically prevent accidental error, like multiplying a quantity by a phone number because they're both INT, or assigning a first name to a last name because they're both CHAR.

In the enterprise SQL world, apparently this sort of error is quite common. It probably doesn't make it into production very often, but undoubtedly slows down development.

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 Hugh on April 29, 2021, 3:06 pm
Quote from tobega on April 28, 2021, 3:25 pm
Quote from Hugh on April 28, 2021, 2:32 pm
Quote from Hugh on April 28, 2021, 10:36 am
Quote from tobega on April 28, 2021, 6:47 am

On the subject of type system for a language capable of hosting a D (and also for Tailspin, of course), we have observed that Tuples must be structurally typed, i.e. the attributes they contain define them as the product type of those attributes.

As a counterpoint to a previous thread here, I propose that Tuples be THE way to create product types.

The latest insight (or train-wreck) that I had, is that we should let attributes define types, i.e. instead of saying that an attribute has a type, we say that an attribute is a type. I think this fits very nicely with the natural join and that we take the position that things with the same name are the same kind of things. It also fits in with a good practice to create specific types for specific things, even if in Java it is a bit of a pain to e.g. create a SupplierName class that simply wraps a String.

So we would declare that there is a type called PNAME of the base type string, and the type called SNAME of the base type string, and you just use them as attributes in the Tuples, the type and the attribute have the same name.

Obviously you cannot assign an SNAME value to a PNAME attribute without casting it. But you could e.g. have a COMPANY_NAME and have SNAME be of the type COMPANY_NAME, which would enable assigning between the two.

So, comments? Good idea? Insane idea?

I've seen other replies.  It doesn't look like a good idea to me but in any case clarification is needed.  Please give examples of type definitions for, e.g., SNAME and PNAME, preferably using TD-like syntax.  I assume you imagine a relation type definition to be like TD's but with just attribute type names as heading components: REL{SNO, SNAME, CITY

What do you think a value of an attribute type looks like.   Please give a literal denoting the supplier name Smith.

What are the implications for the relational RENAME operator?

Hugh

P.S.  Perhaps more appropriate, what about EXTEND?  In particular, I have a query that involves extension with concatenation of FirstName and LastName (with a blank in between).  How is that done?

Answering once for both of your posts.

I wouldn't necessarily change anything from the TD syntax, if that is the syntax you want, so

TUPLE { S# S#, SNAME NAME, STATUS INTEGER, CITY CHAR }
TUPLE { S# S#('S1'), SNAME NAME('Smith'), STATUS 20, CITY 'London' }
TUPLE { S# S#, SNAME NAME, STATUS INTEGER, CITY CHAR } TUPLE { S# S#('S1'), SNAME NAME('Smith'), STATUS 20, CITY 'London' }
TUPLE { S# S#, SNAME NAME, STATUS INTEGER, CITY CHAR }

TUPLE { S# S#('S1'), SNAME NAME('Smith'), STATUS 20, CITY 'London' }

But what would happen is that we would now automatically also have the types SNAME, STATUS and CITY defined, and the "real" type of the CITY attribute would be CITY, but it could be assigned values of the representation type CHAR.

I believe I answered the RENAME case in my reply to Darren.

As for EXTEND, I suppose that would work similarly in that you would have to explicitly assert the conversion to appropriate types. So FirstName is what? CHAR? And LastName might also be CHAR. So lets look at TD syntax:

EXTEND a ADD (CHAR(FirstName)+' '+CHAR(LastName) AS FullName)
EXTEND a ADD (CHAR(FirstName)+' '+CHAR(LastName) AS FullName)
EXTEND a ADD (CHAR(FirstName)+' '+CHAR(LastName) AS FullName)

If FullName has not been previously defined, there will now be a type "FullName CHAR", and any attribute FullName can be assumed to be of type FullName, without needing specification. But it wouldn't necessarily hurt to respecify "FullName CHAR". However, trying to specify e.g. "FullName INT" would not be allowed anywhere, you would have to forego that option.

Oh, I didn't see this one until after I had responded to Dave Voorhis.  So I didn't misunderstand but you have now clarified.  The question now concerns the scope of this defined-on-the-fly type Fullname.  It has to be local to the expression in which it is defined, otherwise I would object strongly.  And it is is local to the expression, I can't see much point.

Hugh

There wouldn't be much point in having it just local to the expression. I propose that the specific type definitions for each attribute that Dave provided is a "best practice" or at least a "good practice", so we can just let them be automatically defined from the attribute definition. This would lead the developer in the right direction for the price of a slight inconvenience on the rare (?) occasion when you would have wanted an attribute with the same name but of a different type.

Quote from AntC on April 28, 2021, 11:58 am

I favour declaring a data dictionary before declaring any tables, and such that attribute names on tables must be drawn from the dictionary. And that no dictionary field be named Date, User, Int, String, Count, Balance, Total, etc.

A-men.

I do mind to note that "attribute names on tables must be drawn from the dictionary" is/could be/might be a less clear-cut question when it comes to the point of also limiting just any program-local RENAME to "introduced attribute names on tables must be also drawn from the dictionary".  While SIRA_PRISE does what it can to encourage the former by design, it does not in any way try to encourage [let alone enforce] the latter, and from previous posts tangential to the subject I seem to recall we don't exactly see eye to eye on that one.

As to "and that no dictionary field be named ...", I understand the concern but addressing it involves a serious pitfall of rendering natural join itself seriously useless.  If the identifier for users is named "ID_USER" in the relvar containing user details, then joining in user details with whatever relvar "references" it will be easier and cheaper if we can just use natural join and the "foreign key" attributes in the "referencing" relvars are also called "ID_USER" instead of "ID_USER_APPRVL" or some such ...