The Forum for Discussion about The Third Manifesto and Related Matters

Please or Register to create posts and topics.

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

PreviousPage 6 of 22Next
Quote from Dave Voorhis on October 24, 2019, 1:53 pm

I fully appreciate that this, unfortunately, dispenses with some very nice D notions -- like tuples and relations having mixed structural/nominal typing; e.g., TUPLE {x INT, y CHAR} is the same type as TUPLE {y CHAR, x INT} -- leaving only the usual Java nominal typing.  E.g., class P {x int, y String} is a different type from class Q {x int, y String} because P is not Q.

The usual approach in compiling languages with tuples for the JVM is to give such classes names that amount to Tuple_x_int_y_char, where int and char are replaced by the JVM's magic letters (see Oracle's writeup).

Quote from johnwcowan on October 24, 2019, 4:35 pm
Quote from Dave Voorhis on October 24, 2019, 9:36 am

It could include things some wouldn't consider typeful -- like XML DTDs (even though it means Document Type Definition)

Despite WP, it is "document type declaration", the <!DOCTYPE...> part of a document, including any external file incorporated, which is what most people think of as "a DTD".  It does indeed declare the type of — that is, the constraints on — the document.

I thought of the DTD as the type, and the <!DOCTYPE ...> as the declaration of that type. E.g., TYPE MyType POSSREP ... ≅ DTD, x MyType ≅ <!DOCTYPE ...>.

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 Erwin on October 24, 2019, 11:32 am

"DOMAIN MyType INT"

That's the same thing that TTM (even sans IM) has already in the form

TYPE MyType POSSREP X {V INT};

"Cast to INT" is then invoking THE_V.  Everything will turn out to have a counterpart.  Iow this DOMAIN thing as presented here is nothing but syntactic sugar.

I'm not commenting on Dave's sketch, but the approach I sketched (earlier in the plethora):

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

consciously breaks RM Pre 1: the set of values in INT's type are also the set of values in S#'s type. But the arithmetic on INT's values is not supported for S#'s type. And of course you can't compare S# 4 = INT 4 because they're of different type.

Complaining about verbosity of selectors as in, e.g. "MYTYPE(X(V(3)))" are il-inspired : relating the appearance of an expression with elements of context (e.g. the type of an assigned-to variable) can facilitate omission of the MYTYPE() part, leaving "X(V(3))".  Inspection of the number of possreps defined for the type can facilitate omission of the X() part, leaving "V(3)".  Inspection of the number of items within the possrep can facilitate omission of the V() part, leaving "3".  Nothing in TTM prohibits any of those, except possibly maybe rule 26 (I wouldn't judge).

 

My complaint was not principally about verbosity of Selectors. I did complain about having multiple PossReps; having abandoned them, I saw no purpose for Selectors: just prefix the typedomain name to values, to disambiguate which domain they're in. I also discussed a 'liberal' variant in which the prefix could be omitted if the applicable domain is clear from context. (I'm guessing it usually is.)

So I see several layers of simplification of the semantics, which the simplified syntax reflects.

Quote from Dave Voorhis on October 24, 2019, 1:53 pm

I don't think I'm misunderstanding, at least not in terms of domains and the type system. Your proposal sounds like fitting a new programming language into an existing programming language, which doesn't require a new programming language -- just code generation and tooling for an existing one.

Which, as it turns out, is exactly what I'm doing with my datasheet tool. It's becoming something that works rather like Rel for manipulating data and data sources, but instead of writing code in Tutorial D, you write code in Java.

And instead of the administrative front-end generating Tutorial D code, it's generating and compiling Java.

The likely difference, and the reason for picking domains as a base, is to avoid some previous bad experiences with DSLs that just generate code, and typically carries a host type system with it. The aim is for the DSL to define its own domains, and the HL talks to the DSL through universal types like number, string and date.

I fully appreciate that this, unfortunately, dispenses with some very nice D notions -- like tuples and relations having mixed structural/nominal typing; e.g., TUPLE {x INT, y CHAR} is the same type as TUPLE {y CHAR, x INT} -- leaving only the usual Java nominal typing. E.g., class P {x int, y String} is a different type from class Q {x int, y String} because P is not Q.

But it turns out that isn't really a show-stopper, and on the client-side, mapping tuples to class instances works -- despite P and Q being different types. Though mediating this is very much a work-in-progress; there may still be better ways to do it.

That's the one I want to avoid. That's very much part of the ORM thing, and I don't see why you need it. The results of a query are a relation. A relation is a set of tuple. A tuple is an object with a set of named properties, getters and setters. Who cares what type it is?

When combined with Java streams -- plus the entirety of the Java ecosystem, plus cross-platform capability including Web -- you get effective blending of client-side and server-side capability without having to embrace a whole new language and possibly a new paradigm.

Though I admit the result is looking a lot closer to being a better ORM (which I guess it is, among other things) than a new D (which it definitely isn't.)

Absolutely. That's the whole reason for embedding a DSL in some well-known HL. Except of course, it's better if Java is not the only choice.

 

Andl - A New Database Language - andl.org
Quote from dandl on October 25, 2019, 6:27 am
Quote from Dave Voorhis on October 24, 2019, 1:53 pm

I don't think I'm misunderstanding, at least not in terms of domains and the type system. Your proposal sounds like fitting a new programming language into an existing programming language, which doesn't require a new programming language -- just code generation and tooling for an existing one.

Which, as it turns out, is exactly what I'm doing with my datasheet tool. It's becoming something that works rather like Rel for manipulating data and data sources, but instead of writing code in Tutorial D, you write code in Java.

And instead of the administrative front-end generating Tutorial D code, it's generating and compiling Java.

The likely difference, and the reason for picking domains as a base, is to avoid some previous bad experiences with DSLs that just generate code, and typically carries a host type system with it. The aim is for the DSL to define its own domains, and the HL talks to the DSL through universal types like number, string and date.

I fully appreciate that this, unfortunately, dispenses with some very nice D notions -- like tuples and relations having mixed structural/nominal typing; e.g., TUPLE {x INT, y CHAR} is the same type as TUPLE {y CHAR, x INT} -- leaving only the usual Java nominal typing. E.g., class P {x int, y String} is a different type from class Q {x int, y String} because P is not Q.

But it turns out that isn't really a show-stopper, and on the client-side, mapping tuples to class instances works -- despite P and Q being different types. Though mediating this is very much a work-in-progress; there may still be better ways to do it.

That's the one I want to avoid. That's very much part of the ORM thing, and I don't see why you need it. The results of a query are a relation. A relation is a set of tuple. A tuple is an object with a set of named properties, getters and setters. Who cares what type it is?

Perhaps I'm misunderstanding what you mean here -- like maybe the context of "type" -- but if you have an object with a set of named properties, getters and setters, that object is an instance of a class, i.e., a "type" in the usual object-oriented colloquial sense. You're at least going to want to know its class name so you can write code that uses it. You'll want to know the class names of its property types, too.

I'm the forum administrator and lead developer of Rel. Email me at dave@armchair.mb.ca with the Subject 'TTM Forum'. Download Rel from https://reldb.org
Quote from Dave Voorhis on October 25, 2019, 10:41 am
Quote from dandl on October 25, 2019, 6:27 am
Quote from Dave Voorhis on October 24, 2019, 1:53 pm

I don't think I'm misunderstanding, at least not in terms of domains and the type system. Your proposal sounds like fitting a new programming language into an existing programming language, which doesn't require a new programming language -- just code generation and tooling for an existing one.

Which, as it turns out, is exactly what I'm doing with my datasheet tool. It's becoming something that works rather like Rel for manipulating data and data sources, but instead of writing code in Tutorial D, you write code in Java.

And instead of the administrative front-end generating Tutorial D code, it's generating and compiling Java.

The likely difference, and the reason for picking domains as a base, is to avoid some previous bad experiences with DSLs that just generate code, and typically carries a host type system with it. The aim is for the DSL to define its own domains, and the HL talks to the DSL through universal types like number, string and date.

I fully appreciate that this, unfortunately, dispenses with some very nice D notions -- like tuples and relations having mixed structural/nominal typing; e.g., TUPLE {x INT, y CHAR} is the same type as TUPLE {y CHAR, x INT} -- leaving only the usual Java nominal typing. E.g., class P {x int, y String} is a different type from class Q {x int, y String} because P is not Q.

But it turns out that isn't really a show-stopper, and on the client-side, mapping tuples to class instances works -- despite P and Q being different types. Though mediating this is very much a work-in-progress; there may still be better ways to do it.

That's the one I want to avoid. That's very much part of the ORM thing, and I don't see why you need it. The results of a query are a relation. A relation is a set of tuple. A tuple is an object with a set of named properties, getters and setters. Who cares what type it is?

Perhaps I'm misunderstanding what you mean here -- like maybe the context of "type" -- but if you have an object with a set of named properties, getters and setters, that object is an instance of a class, i.e., a "type" in the usual object-oriented colloquial sense. You're at least going to want to know its class name so you can write code that uses it. You'll want to know the class names of its property types, too.

Actually I was wrong about setters. The idea is that the return value of a query is a relation, a set of tuples. A tuple has getters to retrieve attribute values in a restricted range of interchange types. It may be convenient to implement a tuple as a class instance (but the type is unimportant) or as a dictionary lookup or some other way. There are no HL operations on tuples other than getting attribute values, and that could equally well use a function API. All operations on relations are in the DSL, all operations in the HL are on attribute values.

The starting point was the 'domain' and I'm interpreting that as a choice to avoid imposing a TTM-like type system on the RA. That means no record structures in the HL that map to tuple types in the DSL. Tuples are DSL tuples and not HL OO classes.

Maybe it doesn't fly, but I'd like to know where exactly it falls out of the air.

Andl - A New Database Language - andl.org
Quote from dandl on October 25, 2019, 1:24 pm
Quote from Dave Voorhis on October 25, 2019, 10:41 am
Quote from dandl on October 25, 2019, 6:27 am
Quote from Dave Voorhis on October 24, 2019, 1:53 pm

I don't think I'm misunderstanding, at least not in terms of domains and the type system. Your proposal sounds like fitting a new programming language into an existing programming language, which doesn't require a new programming language -- just code generation and tooling for an existing one.

Which, as it turns out, is exactly what I'm doing with my datasheet tool. It's becoming something that works rather like Rel for manipulating data and data sources, but instead of writing code in Tutorial D, you write code in Java.

And instead of the administrative front-end generating Tutorial D code, it's generating and compiling Java.

The likely difference, and the reason for picking domains as a base, is to avoid some previous bad experiences with DSLs that just generate code, and typically carries a host type system with it. The aim is for the DSL to define its own domains, and the HL talks to the DSL through universal types like number, string and date.

I fully appreciate that this, unfortunately, dispenses with some very nice D notions -- like tuples and relations having mixed structural/nominal typing; e.g., TUPLE {x INT, y CHAR} is the same type as TUPLE {y CHAR, x INT} -- leaving only the usual Java nominal typing. E.g., class P {x int, y String} is a different type from class Q {x int, y String} because P is not Q.

But it turns out that isn't really a show-stopper, and on the client-side, mapping tuples to class instances works -- despite P and Q being different types. Though mediating this is very much a work-in-progress; there may still be better ways to do it.

That's the one I want to avoid. That's very much part of the ORM thing, and I don't see why you need it. The results of a query are a relation. A relation is a set of tuple. A tuple is an object with a set of named properties, getters and setters. Who cares what type it is?

Perhaps I'm misunderstanding what you mean here -- like maybe the context of "type" -- but if you have an object with a set of named properties, getters and setters, that object is an instance of a class, i.e., a "type" in the usual object-oriented colloquial sense. You're at least going to want to know its class name so you can write code that uses it. You'll want to know the class names of its property types, too.

Actually I was wrong about setters. The idea is that the return value of a query is a relation, a set of tuples. A tuple has getters to retrieve attribute values in a restricted range of interchange types. It may be convenient to implement a tuple as a class instance (but the type is unimportant) or as a dictionary lookup or some other way. There are no HL operations on tuples other than getting attribute values, and that could equally well use a function API. All operations on relations are in the DSL, all operations in the HL are on attribute values.

The starting point was the 'domain' and I'm interpreting that as a choice to avoid imposing a TTM-like type system on the RA. That means no record structures in the HL that map to tuple types in the DSL. Tuples are DSL tuples and not HL OO classes.

Ah, that's exactly where we differ. I'm trying to dispense with the function API to access query results. I did that with the Rel client library, and whilst it's workable, it's awkward -- as DBMS-to-client API's usually are. That's why I'm re-examining tuple-as-class-instance, but only as a way to represent database tuples on the client-side and not as a general database abstraction. The "first great blunder" is not being re-blundered; it's purely a means to make client-side database-driven application coding tastier and less chewy.

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

I did complain about having multiple PossReps

I still don't understand what the problem is supposed to be with them.  Multiple possreps are in effect multiple constructors or factory methods.  A date type might have as possreps a numeric day, month, and year; or a day of the week, an ISO week, and the years used with ISO weeks (a year, in this sense, begins on Sunday of week whose Thursday is in the given Gregorian year); or a day count since some epoch; or many another thing.

Quote from johnwcowan on October 25, 2019, 4:10 pm
Quote from AntC on October 24, 2019, 8:52 pm

I did complain about having multiple PossReps

I still don't understand what the problem is supposed to be with them.

Each PossRep is required to be total and updatable-through via a particular component, not necessarily the whole, em, constructor. IOW they're not merely for obtaining an alternative view of the data structure.

So previous debates have raged about cartesian vs polar coordinates: for polar, what should be the angle if the displacement is zero? If our angle is in radians, how to represent irrationals like π? Do we allow setting the angle to greater than 2π, in which case how is that represented in cartesian, and if we get it back in polar will we find the value isn't what we set but is modulo 2π?

Hugh's original intent with PossReps was for things like units conversion: metric ↔ imperial, for which the idea is fine. But if we're needing a PossRep in common to mediate between different ways to represent squares/rectangles/polygons/circles/ellipses/figures on the plane (ref the Inheritance Model debate), we're going to bump into the same issues as with cartesian/polar.

  Multiple possreps are in effect multiple constructors or factory methods.  A date type might have as possreps a numeric day, month, and year; or a day of the week, an ISO week, and the years used with ISO weeks (a year, in this sense, begins on Sunday of week whose Thursday is in the given Gregorian year); or a day count since some epoch; or many another thing.

Yes differing date formats is one of the intended uses, along same lines as imperial/metric.

As I understand it with multiple factory methods, there's one representation that's the declared/base/mapped-to-physical format for the type; the other methods convert from their arguments to base; there's no guarantee of a conversion back from every possible base value to the method's arguments. And there's no guarantee a 'round trip' from the factory method's arguments to base back to arguments will give you the values you started with.

Quote from AntC on October 25, 2019, 10:25 pm

So previous debates have raged about cartesian vs polar coordinates: for polar, what should be the angle if the displacement is zero?

Any value the implementation chooses to return, I suppose.  Asking three different Schemes (all of which use rectangular representations) for answers, I get back either inexact 0 or inexact π.  However, Pure (which is not a Scheme or even a Lisp) maintains separate internal representations for rectangular and polar complex numbers.  The discernible difference is that if you ask for the real and imaginary parts of a rectangular number or the magnitude and angle of a polar number, you get back the value you put in, whereas in the two contrary cases you might not.

If our angle is in radians, how to represent irrationals like π?

Inexactly, how else?  People have occasionally thought about providing numbers that are exact multiples of π (in the sense that imaginary numbers are real multiples of i), but I don't know that it's ever been done in practice.

As I understand it with multiple factory methods, there's one representation that's the declared/base/mapped-to-physical format for the type;

Pure complex numbers are a counterexample, and in Java or C#, factory methods on Foo might return objects whose dynamic types are different private subtypes of Foo with partly or completely different internal representations.

Indeed, Java 9 and later have two internal representations of String objects: 8 bits per UTF-16 codepoint if all codepoints are less than 256, and the full 16 bits if the String contains at least one larger codepoint.  This is completely invisible to Java users, who see Strings as containing 16-bit Java chars (really codepoints) in either case.  Larceny (a Scheme) juggles three internal representations of Scheme strings (which, unlike Java strings, are mutable unless they were created from literals in the code): an 8-bit, a 16-bit, and a 32-bit representation, and will if necessary change the representation invisibly to Scheme (which sees only characters) whenever a mutation is done.

And there's no guarantee a 'round trip' from the factory method's arguments to base back to arguments will give you the values you started with.

No, but hopefully the round-trip arguments -> object1 -> other arguments -> object2 will provide equal (i.e, indiscernible) objects.

PreviousPage 6 of 22Next