The Forum for Discussion about The Third Manifesto and Related Matters

Please or Register to create posts and topics.

A TTM Tuple is not a Record

Quote from Dave Voorhis on May 4, 2020, 9:54 am
Quote from dandl on May 4, 2020, 1:19 am
Quote from Dave Voorhis on May 3, 2020, 3:30 pm
Quote from dandl on May 3, 2020, 2:49 pm
Quote from Dave Voorhis on May 3, 2020, 7:14 am

I didn't mean RM Pre 18. I meant OO Pre 1.

But the solution I propose completely satisfies OO Pre 1, to exactly the same extent as C#. Every expression, variable, attribute, component, argument and operator in the set of types I described earlier is checked by the compiler for safety using the native features of the C# compiler. What do you think is  missing?

Given C# representations of tuple types T1 and tuple T2, where do you statically determine whether they are type-compatible or not?

They have separate definitions. TupS is one type, TupP is a different type.

What do you mean by 'compatible'? That's not a term used in TTM.

It's conventional terminology. Loosely, type-compatibility is the opposite of a type mismatch. In TTM terms, T1 is type-compatible with type T2 if values of T1 can be assigned to a variable or parameter of type T2.

The point I wanted to make is while the target languages have various kinds of type compatibility (such as assignment compatibility, covariance and contra-variance), these are not TTM requirements. TTM has the mysterious observation that 'Tuple types TUPLE H1 and TUPLE H2 shall be equal if and only if H1 = H2', but type equality is not defined.

My reading of TTM is that two types with the same name are the same type, and two types with different names are not. This is made explicitly clear for scalar types; for non-scalar types, since the names are precisely TUPLE H and RELATION H respectively, I read it as also true. [It happens to be the case that TD allows the same type to be declared with attributes given in a different order, but they are still the same type, not just 'compatible'.]

So the for D/GP restriction is explicitly:

  • every tuple type with heading H has the same name, because there is only one.
  • every relation type with heading H has the same name, because there is only one.

This is TTM compliant.

If TupS is one type and TupP is a different type, assuming TupS is the C# equivalent to

TUPLE {x INT, y CHAR}

TUPLE {x INT, y CHAR} and TupP is the C# equivalent to

TUPLE {y CHAR, x INT}

TUPLE {y CHAR, x INT}, are they type-compatible (as I would expect them to be per TTM's structural typing)?

Or are they type-incompatible (as I would expect them to be per C# nominative typing)?

Those are user-defined scalar types, not tuple types. The corresponding tuple type is:

public class TupPoint : TupleBase {
  public int X { get { return (int)_values[0]; } }
  public int Y { get { return (int)_values[1]; } }

  static TupPoint() {
    Heading = new string[] { "X", "Y" };
  }

  public TupPoint(int X, int Y) : base(
    new object[] { X, Y }) {
  }
}

It should be trivial to prevent a relvar variable holding a tuple value, assuming the former is declared as (say) class Relvar and the latter class Tuple. How do you ensure that a C# representation of Tuple1 where Tuple1 is TUPLE {x INT, y CHAR} is type-compatible with Tuple2 where Tuple2 is TUPLE {y CHAR, x INT}?

You're still thinking records, and these are not records. That question cannot arise. It has no meaning.

No, I'm not "thinking records", and I'm not sure what that means.

I'm thinking of TTM's tuples (and relations) and its use of structural typing as opposed to C#'s classes and structs and its use of nominative typing. How are you reconciling these distinct approaches?

You are thinking of the representation of a tuple type in the target language as being akin to a record, and it is not. It's a specially constructed data structure per the above. User-defined scalar types are records, tuple types are not.

Let me try to clarify what I claim.

  • D/GP is a way of representing the TTM D type system in a modern general purpose strongly typed programming language.
  • As described, it fully complies with TTM (excluding Possreps and the IM).
  • The means used are 100% native code, using the native type system to ensure type safety.
  • There are some rules about how TTM scalar and non-scalar types are constructed and used. Failure to comply is 'undefined behaviour' (see note).
  • The RA requirements in RM Pre 18 as to 'type inference' are satisfied (see note).
  • There are some other rules in TTM (RM Pre 3a, 3d, Pro 7,8); failure to comply with these is 'undefined behaviour' (see note).

A GP language will inevitably allow a wide range of behaviours, some of which violate TTM requirements. You can write complying code, but the compiler isn't going to help you. So you have 3 choices:

  1. Leave it as 'undefined behaviour' like C/C++, and let the programmer deal with compliance issues.
  2. Enforce the rules at run time, as type errors, assertions or whatever.
  3. Modify or extend the compiler (not the language) to add TTM compliance checking.

For example (as per your question above), one of the rules is that you are only allowed to declare one tuple type with any given heading. Given that a heading is a set of attribute names (and associated types), declaring Tuple2 with the same heading as Tuple1 was not allowed. Every tuple with that heading is a Tuple1, and type safety is guaranteed. This complies with RM Pre 6.

I would expect that early implementations of a D/GP would enforce chosen rules at runtime in a variety of ways, possibly including reflection. If it turns out to be a good idea, a modified compiler with a 'TTM mode' and/or @TupleType  annotations would be able to enforce the rules at compile time.

If I've missed something please point it out, but it all looks solid to me.

So if I understand you correctly, the C# equivalent of TUPLE {x INT, y CHAR} and the C# equivalent of TUPLE {y CHAR, x INT} are treated as distinct types. In other words, you adhere to C#'s nominative typing and dispense with TTM's structural typing?

Not at all. What you have shown is an approximation of the TD code that implements TTM Pre 6. What I have shown above is my C# code that implements TTM Pre 6. There is no structural typing in TTM that I can see, although the TD code could be interpreted that way. I see a set of requirements in RM Pre 6 to be met and this approach meets them all.

Andl - A New Database Language - andl.org

Why do we try to map tuple into records?

Who is "we"? And do all of those people "try to map"? And what do these people mean by "records"?

 

David this discussion has already gone three times round the town before I've even laced up my boots. If I've missed the following, it's hardly something I'm going to apologise about: The only term in your title that's well-defined is 'TTM tuple'. I see no definition of 'Record'; and since there are at least as many definitions of 'Record' as there are languages claiming to implement such a thing; I find your title vacuous.

Also please don't use 'is [not]' like that. A TTM tuple is not a kettle of fish. So what? There's enough in the discussion to make me think you're confusing TTM's logical model/PossRep for (what it calls) 'tuples'; with a Programming Language's syntax or implementation or PhysRep. TTM does not prescribe syntax; neither does it prescribe implementation; nor PhysRep.

If you mean something like: a TTM Tuple cannot be implemented as a Record going by the definition of 'Record' in any language/semantics David knows, you'll have to work harder to show that's not just due to your narrowness of knowledge and inability to implement TTM's semantics.

There would appear to be implementations of TTM semantics in some contemporary programming languages. Are you saying they're bogus in some sense? Are you saying they *should* use 'Records' as defined in those languages, but they aren't, and there's something wrong with that?

If some implementation's representation for TTM tuples does not use what that language calls 'Record', so what? The quality of mercy is not a kettle of fish.

 

Quote from AntC on May 5, 2020, 6:24 am

Why do we try to map tuple into records?

Who is "we"? And do all of those people "try to map"? And what do these people mean by "records"?

Agreed, the language is loose. However, I thought it was pretty obvious that I was using 'record' as a generic term to refer to any or all of the record-like features in any or all of the common strongly typed compiled languages. They variously go under names like structclass or record.They trace their roots historically back to Cobol REDEFINES, PL/I, some Algol variants, Pascal and C. This article covers the subject widely if not well: https://en.wikipedia.org/wiki/Record_(computer_science). Are we on the same page yet?

The 'we' is at least me, you and Dave, bemoaning the difficulties in reconciling the non-scalar types in TTM with record types in these languages. I think it's why you're pursuing Hugs. My proposition is: don't.

 

David this discussion has already gone three times round the town before I've even laced up my boots. If I've missed the following, it's hardly something I'm going to apologise about: The only term in your title that's well-defined is 'TTM tuple'. I see no definition of 'Record'; and since there are at least as many definitions of 'Record' as there are languages claiming to implement such a thing; I find your title vacuous.

Also please don't use 'is [not]' like that. A TTM tuple is not a kettle of fish. So what? There's enough in the discussion to make me think you're confusing TTM's logical model/PossRep for (what it calls) 'tuples'; with a Programming Language's syntax or implementation or PhysRep. TTM does not prescribe syntax; neither does it prescribe implementation; nor PhysRep.

If you mean something like: a TTM Tuple cannot be implemented as a Record going by the definition of 'Record' in any language/semantics David knows, you'll have to work harder to show that's not just due to your narrowness of knowledge and inability to implement TTM's semantics.

No, that's not it. In most of those languages record-like constructs are a major part of the means to define new types, so of course an implementation is going to use them. The mistake is trying to pretend that a tuple is a record when it so obviously isn't. TTM makes that very clear.

There would appear to be implementations of TTM semantics in some contemporary programming languages. Are you saying they're bogus in some sense? Are you saying they *should* use 'Records' as defined in those languages, but they aren't, and there's something wrong with that?

If some implementation's representation for TTM tuples does not use what that language calls 'Record', so what? The quality of mercy is not a kettle of fish.

All the implementations I know of have taken TD as an indication to design a whole new programming language with a novel type system. I did exactly that with Andl. My proposition is: don't. Using the strategy I've outlined the TTM requirements for its D language can be fully satisfied (except for Possreps and the IM) using the language features and native type system of any modern strongly-typed GP language.

I'm saying that using the features of language X to build a compiler and runtime implementation of D (such as Rel or Andl) is the wrong way to go. Instead, add some types and libraries and rules on how to use them and X becomes a D.

Andl - A New Database Language - andl.org
Quote from dandl on May 5, 2020, 7:43 am

...

All the implementations I know of have taken TD as an indication to design a whole new programming language with a novel type system. I did exactly that with Andl. My proposition is: don't. Using the strategy I've outlined the TTM requirements for its D language can be fully satisfied (except for Possreps and the IM) using the language features and native type system of any modern strongly-typed GP language.

I'm saying that using the features of language X to build a compiler and runtime implementation of D (such as Rel or Andl) is the wrong way to go. Instead, add some types and libraries and rules on how to use them and X becomes a D.

It becomes D-like, maybe. I'm afraid I find your descriptions of how you're making C# into a D more baffling with each post. Now it looks to me like you're treating D compliance as a sort of word game, where you achieve D compliance by choosing the right set of words to describe it rather than using programming language constructs to implement it.

I guess I'll have to wait to see the result, because the explanations aren't making sense to me.

As for efforts to create a new language, I see no reason to deprecate them, or to position efforts to turn an existing general-purpose language into a D or a D-like thing either above or below them. They're all equally worthwhile efforts, though like all choices in IT, each approach gains you some things and takes away others. Everything has its trade-offs.

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 dandl on May 5, 2020, 4:30 am
Quote from Dave Voorhis on May 4, 2020, 9:54 am
Quote from dandl on May 4, 2020, 1:19 am
Quote from Dave Voorhis on May 3, 2020, 3:30 pm
Quote from dandl on May 3, 2020, 2:49 pm
Quote from Dave Voorhis on May 3, 2020, 7:14 am

I didn't mean RM Pre 18. I meant OO Pre 1.

But the solution I propose completely satisfies OO Pre 1, to exactly the same extent as C#. Every expression, variable, attribute, component, argument and operator in the set of types I described earlier is checked by the compiler for safety using the native features of the C# compiler. What do you think is  missing?

Given C# representations of tuple types T1 and tuple T2, where do you statically determine whether they are type-compatible or not?

They have separate definitions. TupS is one type, TupP is a different type.

What do you mean by 'compatible'? That's not a term used in TTM.

It's conventional terminology. Loosely, type-compatibility is the opposite of a type mismatch. In TTM terms, T1 is type-compatible with type T2 if values of T1 can be assigned to a variable or parameter of type T2.

The point I wanted to make is while the target languages have various kinds of type compatibility (such as assignment compatibility, covariance and contra-variance), these are not TTM requirements. TTM has the mysterious observation that 'Tuple types TUPLE H1 and TUPLE H2 shall be equal if and only if H1 = H2', but type equality is not defined.

My reading of TTM is that two types with the same name are the same type, and two types with different names are not. This is made explicitly clear for scalar types; for non-scalar types, since the names are precisely TUPLE H and RELATION H respectively, I read it as also true. [It happens to be the case that TD allows the same type to be declared with attributes given in a different order, but they are still the same type, not just 'compatible'.]

So the for D/GP restriction is explicitly:

  • every tuple type with heading H has the same name, because there is only one.
  • every relation type with heading H has the same name, because there is only one.

This is TTM compliant.

If TupS is one type and TupP is a different type, assuming TupS is the C# equivalent to

TUPLE {x INT, y CHAR}

TUPLE {x INT, y CHAR} and TupP is the C# equivalent to

TUPLE {y CHAR, x INT}

TUPLE {y CHAR, x INT}, are they type-compatible (as I would expect them to be per TTM's structural typing)?

Or are they type-incompatible (as I would expect them to be per C# nominative typing)?

Those are user-defined scalar types, not tuple types. The corresponding tuple type is:

I'm fairly sure TUPLE {x INT, y CHAR} and TUPLE {y CHAR, x INT} are tuple types -- and likewise, RELATION {x INT, y CHAR} is a relation type -- not scalar types. CHAR and INT are scalar types.

Or are you alluding to some distinction between types and type generators?

public class TupPoint : TupleBase {
public int X { get { return (int)_values[0]; } }
public int Y { get { return (int)_values[1]; } }
static TupPoint() {
Heading = new string[] { "X", "Y" };
}
public TupPoint(int X, int Y) : base(
new object[] { X, Y }) {
}
}
public class TupPoint : TupleBase { public int X { get { return (int)_values[0]; } } public int Y { get { return (int)_values[1]; } } static TupPoint() { Heading = new string[] { "X", "Y" }; } public TupPoint(int X, int Y) : base( new object[] { X, Y }) { } }
public class TupPoint : TupleBase {
  public int X { get { return (int)_values[0]; } }
  public int Y { get { return (int)_values[1]; } }

  static TupPoint() {
    Heading = new string[] { "X", "Y" };
  }

  public TupPoint(int X, int Y) : base(
    new object[] { X, Y }) {
  }
}

It should be trivial to prevent a relvar variable holding a tuple value, assuming the former is declared as (say) class Relvar and the latter class Tuple. How do you ensure that a C# representation of Tuple1 where Tuple1 is TUPLE {x INT, y CHAR} is type-compatible with Tuple2 where Tuple2 is TUPLE {y CHAR, x INT}?

You're still thinking records, and these are not records. That question cannot arise. It has no meaning.

No, I'm not "thinking records", and I'm not sure what that means.

I'm thinking of TTM's tuples (and relations) and its use of structural typing as opposed to C#'s classes and structs and its use of nominative typing. How are you reconciling these distinct approaches?

You are thinking of the representation of a tuple type in the target language as being akin to a record, and it is not. It's a specially constructed data structure per the above. User-defined scalar types are records, tuple types are not.

I'm not thinking of anything "as being akin to a record."

I'm not using the term "record" at all.

I'm using the term tuple, per TTM, and using examples of Tutorial D syntax with known semantics.

Let me try to clarify what I claim.

  • D/GP is a way of representing the TTM D type system in a modern general purpose strongly typed programming language.
  • As described, it fully complies with TTM (excluding Possreps and the IM).
  • The means used are 100% native code, using the native type system to ensure type safety.
  • There are some rules about how TTM scalar and non-scalar types are constructed and used. Failure to comply is 'undefined behaviour' (see note).
  • The RA requirements in RM Pre 18 as to 'type inference' are satisfied (see note).
  • There are some other rules in TTM (RM Pre 3a, 3d, Pro 7,8); failure to comply with these is 'undefined behaviour' (see note).

A GP language will inevitably allow a wide range of behaviours, some of which violate TTM requirements. You can write complying code, but the compiler isn't going to help you. So you have 3 choices:

  1. Leave it as 'undefined behaviour' like C/C++, and let the programmer deal with compliance issues.
  2. Enforce the rules at run time, as type errors, assertions or whatever.
  3. Modify or extend the compiler (not the language) to add TTM compliance checking.

For example (as per your question above), one of the rules is that you are only allowed to declare one tuple type with any given heading. Given that a heading is a set of attribute names (and associated types), declaring Tuple2 with the same heading as Tuple1 was not allowed. Every tuple with that heading is a Tuple1, and type safety is guaranteed. This complies with RM Pre 6.

I would expect that early implementations of a D/GP would enforce chosen rules at runtime in a variety of ways, possibly including reflection. If it turns out to be a good idea, a modified compiler with a 'TTM mode' and/or @TupleType  annotations would be able to enforce the rules at compile time.

If I've missed something please point it out, but it all looks solid to me.

So if I understand you correctly, the C# equivalent of TUPLE {x INT, y CHAR} and the C# equivalent of TUPLE {y CHAR, x INT} are treated as distinct types. In other words, you adhere to C#'s nominative typing and dispense with TTM's structural typing?

Not at all. What you have shown is an approximation of the TD code that implements TTM Pre 6. What I have shown above is my C# code that implements TTM Pre 6. There is no structural typing in TTM that I can see, although the TD code could be interpreted that way. I see a set of requirements in RM Pre 6 to be met and this approach meets them all.

Sorry, I find this rather baffling. You keep showing trivial (and somewhat strange) C# code examples without explanation, as if they're self-explanatory. They aren't.

I thought my questions were simple, but your responses to them suggests a different interpretation of TTM from mine.

Again, I guess I'll have to see your code when it's done.

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 May 5, 2020, 6:24 am

Why do we try to map tuple into records?

Who is "we"? And do all of those people "try to map"? And what do these people mean by "records"?

 

David this discussion has already gone three times round the town before I've even laced up my boots. If I've missed the following, it's hardly something I'm going to apologise about: The only term in your title that's well-defined is 'TTM tuple'. I see no definition of 'Record'; and since there are at least as many definitions of 'Record' as there are languages claiming to implement such a thing; I find your title vacuous.

Also please don't use 'is [not]' like that. A TTM tuple is not a kettle of fish. So what? There's enough in the discussion to make me think you're confusing TTM's logical model/PossRep for (what it calls) 'tuples'; with a Programming Language's syntax or implementation or PhysRep. TTM does not prescribe syntax; neither does it prescribe implementation; nor PhysRep.

If you mean something like: a TTM Tuple cannot be implemented as a Record going by the definition of 'Record' in any language/semantics David knows, you'll have to work harder to show that's not just due to your narrowness of knowledge and inability to implement TTM's semantics.

There would appear to be implementations of TTM semantics in some contemporary programming languages. Are you saying they're bogus in some sense? Are you saying they *should* use 'Records' as defined in those languages, but they aren't, and there's something wrong with that?

If some implementation's representation for TTM tuples does not use what that language calls 'Record', so what? The quality of mercy is not a kettle of fish.

 

FWIW he's probably referring to 'record' as in 'new record feature' as announced (already out ???) for java 14.  Dave brought that up in connection with the new directions he's taking.

I probably share the majority of the sentiments you are expressing in this post, but I'm not going to spend any time debating that.  One can keep doing that forever.

I've got a system where I can write

Relation r = getConnection(...).startTransaction(...).execquery("query syntax here");

Collection <MyJavaClass> c = SiraPriseMagic.convertToJavaThing(r);

and after I have changed state in some of those MyJavaClass objects

getConnection(...).startTransaction(...).execServerAssignmentCommand(new ServerMultipleAssignmentCommand(obj1.dbUpdateCommand(), obj2.dbDeleteCommand, ...));

Seems powerful enough for me.  It's always going to be data sublanguage paradigm, so in that sense it's never going to be compliant with the TTM ideal of a "unified D" but I can live with that.

Quote from Dave Voorhis on May 5, 2020, 8:22 am
Quote from dandl on May 5, 2020, 4:30 am
Quote from Dave Voorhis on May 4, 2020, 9:54 am
Quote from dandl on May 4, 2020, 1:19 am
Quote from Dave Voorhis on May 3, 2020, 3:30 pm
Quote from dandl on May 3, 2020, 2:49 pm
Quote from Dave Voorhis on May 3, 2020, 7:14 am

I didn't mean RM Pre 18. I meant OO Pre 1.

 

They have separate definitions. TupS is one type, TupP is a different type.

 

The point I wanted to make is while the target languages have various kinds of type compatibility (such as assignment compatibility, covariance and contra-variance), these are not TTM requirements. TTM has the mysterious observation that 'Tuple types TUPLE H1 and TUPLE H2 shall be equal if and only if H1 = H2', but type equality is not defined.

Headings are sets; sets of <A,T> ordered pairs. Two sets are equal just in case they have the same member elements. Comparing Attributes and Types to determine the equality of <A,T> is in the metalanguage, not within the semantics of a D . In implementation terms, I'd say that's in the type system, so the comparison might be static at compile time.

My reading of TTM is that two types with the same name are the same type, and two types with different names are not. This is made explicitly clear for scalar types; for non-scalar types, since the names are precisely TUPLE H and RELATION H respectively, I read it as also true. [It happens to be the case that TD allows the same type to be declared with attributes given in a different order, but they are still the same type, not just 'compatible'.]

I'm fairly sure TUPLE {x INT, y CHAR} and TUPLE {y CHAR, x INT} are tuple types -- and likewise, RELATION {x INT, y CHAR} is a relation type -- not scalar types. CHAR and INT are scalar types.

It should be trivial to prevent a relvar variable holding a tuple value, assuming the former is declared as (say) class Relvar and the latter class Tuple. How do you ensure that a C# representation of Tuple1 where Tuple1 is TUPLE {x INT, y CHAR} is type-compatible with Tuple2 where Tuple2 is TUPLE {y CHAR, x INT}?

You're still thinking records, and these are not records. That question cannot arise. It has no meaning.

No, I'm not "thinking records", and I'm not sure what that means.

I'm thinking of TTM's tuples (and relations) and its use of structural typing as opposed to C#'s classes and structs and its use of nominative typing. How are you reconciling these distinct approaches?

You are thinking of the representation of a tuple type in the target language as being akin to a record, and it is not. It's a specially constructed data structure per the above. User-defined scalar types are records, tuple types are not.

I'm not thinking of anything "as being akin to a record."

I'm not using the term "record" at all.

I think that's ultra-sensible. TTM doesn't use the term 'record'. As a side-note Haskell (Language report 1998, 2010) doesn't use the term 'record'/it doesn't appear in the index. The language has something the Report calls 'Datatypes with field labels'.

David said in an earlier reply

I thought it was pretty obvious that I was using 'record' as a generic term to refer to any or all of the record-like features in any or all of the common strongly typed compiled languages.

Replacing 'record' with 'record-like features' is getting nowhere. To the extent Haskell counts as a "strongly typed compiled language", it doesn't have a thing officially called 'record'. Haskellers loosely talk of the language's 'record system', usually with some derogatory sense applied to it. Perhaps they should stop complaining that a system not claiming to be a record system is not in fact a record system.

The Java language proposal Dave mentioned recently 'Data Classes and Sealed Types for Java' also doesn't officially call anything a 'record'. (The word does appear informally in both the proposal write-up and some of the blogs.) In that discussion, I drew parallels between the Java proposal and features in Haskell, comparing non-records to non-records, it seems.

Clearly wise heads in the industry don't use the term 'record' because it fails to convey anything useful or coherent.

They variously go under names like struct,  class or record.They trace their roots historically back to Cobol REDEFINES, PL/I, some Algol variants, Pascal and C.

Lumping all those together is resulting in mush. Perhaps those features of those languages are related historically. Gawdelpus if you're trying to include REDEFINES: what a crock of ordure. There's no core concept sufficiently in common between those examples to give me any idea what it is you're claiming a TTM tuple is not. I might say a Pascal record is not a Record.

Explaining yourself with C# code is again not conveying anything. I wouldn't know whether it's trivial or strange. If you have some important not-a-record concept, you should be able to explain it at the PossRep level comparable to TTM's Pres and Pros. A possible Pro might be: there shall be no way to access fields by position. In which case Haskell's datatypes and Java's new wotsit are already excluded.

All the implementations I know of have taken TD as an indication to design a whole new programming language with a novel type system. I did exactly that with Andl. My proposition is: don't. Using the strategy I've outlined the TTM requirements for its D language can be fully satisfied (except for Possreps and the IM) using the language features and native type system of any modern strongly-typed GP language.

I'm saying that using the features of language X to build a compiler and runtime implementation of D (such as Rel or Andl) is the wrong way to go. Instead, add some types and libraries and rules on how to use them and X becomes a D.

It becomes D-like, maybe. I'm afraid I find your descriptions of how you're making C# into a D more baffling with each post. Now it looks to me like you're treating D compliance as a sort of word game, where you achieve D compliance by choosing the right set of words to describe it rather than using programming language constructs to implement it.

Now you've lost me. What is 'D-like'? TTM says:

D: The Manifesto makes repeated reference to a hypothetical language it calls D. However, the name D is
merely a useful generic label; any language that conforms to the principles laid down in the Manifesto is a
valid D (and any language that fails so to conform is not a valid D).

I say that the proposal I put forward shows how a GP language can be made to largely conform to the principles laid down. What more would it need to do?

I guess I'll have to wait to see the result, because the explanations aren't making sense to me.

As for efforts to create a new language, I see no reason to deprecate them, or to position efforts to turn an existing general-purpose language into a D or a D-like thing either above or below them. They're all equally worthwhile efforts, though like all choices in IT, each approach gains you some things and takes away others. Everything has its trade-offs.

I'm not deprecating, I'm saying that there have been several successful implementations and no-one wants to use them. If there is to be a D that others use, this is a way that might get there.

Andl - A New Database Language - andl.org
Quote from Dave Voorhis on May 5, 2020, 8:22 am
Quote from dandl on May 5, 2020, 4:30 am
Quote from Dave Voorhis on May 4, 2020, 9:54 am
Quote from dandl on May 4, 2020, 1:19 am
Quote from Dave Voorhis on May 3, 2020, 3:30 pm
Quote from dandl on May 3, 2020, 2:49 pm
Quote from Dave Voorhis on May 3, 2020, 7:14 am

I didn't mean RM Pre 18. I meant OO Pre 1.

But the solution I propose completely satisfies OO Pre 1, to exactly the same extent as C#. Every expression, variable, attribute, component, argument and operator in the set of types I described earlier is checked by the compiler for safety using the native features of the C# compiler. What do you think is  missing?

Given C# representations of tuple types T1 and tuple T2, where do you statically determine whether they are type-compatible or not?

They have separate definitions. TupS is one type, TupP is a different type.

What do you mean by 'compatible'? That's not a term used in TTM.

It's conventional terminology. Loosely, type-compatibility is the opposite of a type mismatch. In TTM terms, T1 is type-compatible with type T2 if values of T1 can be assigned to a variable or parameter of type T2.

The point I wanted to make is while the target languages have various kinds of type compatibility (such as assignment compatibility, covariance and contra-variance), these are not TTM requirements. TTM has the mysterious observation that 'Tuple types TUPLE H1 and TUPLE H2 shall be equal if and only if H1 = H2', but type equality is not defined.

My reading of TTM is that two types with the same name are the same type, and two types with different names are not. This is made explicitly clear for scalar types; for non-scalar types, since the names are precisely TUPLE H and RELATION H respectively, I read it as also true. [It happens to be the case that TD allows the same type to be declared with attributes given in a different order, but they are still the same type, not just 'compatible'.]

So the for D/GP restriction is explicitly:

  • every tuple type with heading H has the same name, because there is only one.
  • every relation type with heading H has the same name, because there is only one.

This is TTM compliant.

If TupS is one type and TupP is a different type, assuming TupS is the C# equivalent to

TUPLE {x INT, y CHAR}

TUPLE {x INT, y CHAR} and TupP is the C# equivalent to

TUPLE {y CHAR, x INT}

TUPLE {y CHAR, x INT}, are they type-compatible (as I would expect them to be per TTM's structural typing)?

Or are they type-incompatible (as I would expect them to be per C# nominative typing)?

Those are user-defined scalar types, not tuple types. The corresponding tuple type is:

I'm fairly sure TUPLE {x INT, y CHAR} and TUPLE {y CHAR, x INT} are tuple types -- and likewise, RELATION {x INT, y CHAR} is a relation type -- not scalar types. CHAR and INT are scalar types.

Sorry, I think there was a bad edit in there somewhere. What I meant is that those specific syntactic forms do not illustrate structural typing. They are examples of the way that TD allows the same type to be declared with the attributes ordered differently, but both of those examples are the same type. They have the same name ('TUPLE H' as per TTM), they are one and the same type. There is only ever one type with that heading, regardless of whether it is declared in code or arises as the result of a relational operation.

TD also has user defined scalar types, in which types with the same components can have different names and are different types.

Sorry, I find this rather baffling. You keep showing trivial (and somewhat strange) C# code examples without explanation, as if they're self-explanatory. They aren't.

I thought my questions were simple, but your responses to them suggests a different interpretation of TTM from mine.

Again, I guess I'll have to see your code when it's done.

I've refined them a little, but they're not going to change a whole lot. This is the definition for the S tuple type.

public class TupS : TupleBase {
  public readonly static string[] Heading = { "SNo", "Sname", "Status", "City" };

  public string Sno { get { return (string)_values[0]; } }
  public string Sname { get { return (string)_values[1]; } }
  public int Status { get { return (int)_values[2]; } }
  public string City { get { return (string)_values[3]; } }

  public TupS(string Sno, string Sname, int Status, string City) : base(
    new object[] { Sno, Sname, Status, City }) {
  }
}

Here is the S relation type.

public class RelS : RelationBase<TupS> {
  public RelS(IList<TupS> tuples) : base(tuples) {
  }
}

And here is some sample data and a simple example.

public static RelS S = new RelS(
  new List<TupS> {
    new TupS( "S1", "Smith", 20, "London" ),
    new TupS( "S2", "Jones", 10, "Paris" ),
    new TupS( "S3", "Blake", 30, "Paris" ),
    new TupS( "S4", "Clark", 20, "London" ),
    new TupS( "S5", "Adams", 30, "Athens" ),
  });

  Console.WriteLine(S.Select(t => t.Status < 20));

Pretty much all of TTM except for RM Pre 18 is already there. I'm still working on that part (as well as codifying some rules).

 

Andl - A New Database Language - andl.org
Quote from dandl on May 5, 2020, 2:20 pm

All the implementations I know of have taken TD as an indication to design a whole new programming language with a novel type system. I did exactly that with Andl. My proposition is: don't. Using the strategy I've outlined the TTM requirements for its D language can be fully satisfied (except for Possreps and the IM) using the language features and native type system of any modern strongly-typed GP language.

I'm saying that using the features of language X to build a compiler and runtime implementation of D (such as Rel or Andl) is the wrong way to go. Instead, add some types and libraries and rules on how to use them and X becomes a D.

It becomes D-like, maybe. I'm afraid I find your descriptions of how you're making C# into a D more baffling with each post. Now it looks to me like you're treating D compliance as a sort of word game, where you achieve D compliance by choosing the right set of words to describe it rather than using programming language constructs to implement it.

Now you've lost me. What is 'D-like'? TTM says:

D: The Manifesto makes repeated reference to a hypothetical language it calls D. However, the name D is
merely a useful generic label; any language that conforms to the principles laid down in the Manifesto is a
valid D (and any language that fails so to conform is not a valid D).

I say that the proposal I put forward shows how a GP language can be made to largely conform to the principles laid down. What more would it need to do?

D-like would be meeting some pre/pro-scriptions but not others, but in the spirit of D if not the letter.

I guess I'll have to wait to see the result, because the explanations aren't making sense to me.

As for efforts to create a new language, I see no reason to deprecate them, or to position efforts to turn an existing general-purpose language into a D or a D-like thing either above or below them. They're all equally worthwhile efforts, though like all choices in IT, each approach gains you some things and takes away others. Everything has its trade-offs.

I'm not deprecating, I'm saying that there have been several successful implementations and no-one wants to use them. If there is to be a D that others use, this is a way that might get there.

I get a reasonable number of Rel downloads and some forks on GitHub. I'm happy with what it's achieved, which is better than I expected when I started working on it.

But if you're talking about mass adoption, I think you need to consider what dramatic improvement a D of any kind will make over and above existing alternatives. Otherwise, it will only attract the usual niche audience of experimenters, hobbyists, and database obsessives like ourselves.

To make a market dent a D needs to make a dramatic difference. That's the problem with all the D implementations so far; they're perfectly adequate but none are disruptive. They don't make a big enough difference in day-to-day programming to unseat SQL or (facilities within) popular programming languages.

By way of analogy, people aren't willing to give up their old family Ford when all we're offering is the same car with a different engine that delivers the same fuel economy as the old one, and the grill's a pretty shape.

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