The Forum for Discussion about The Third Manifesto and Related Matters

You need to log in to create posts and topics.

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

Quote from AntC on March 16, 2020, 2:30 am
Quote from Dave Voorhis on March 15, 2020, 8:25 pm
Quote from Erwin on March 15, 2020, 2:24 pm
Quote from Hugh on March 15, 2020, 12:46 pm

Personally I see little point in trying to guess what Codd really meant by "domain".  I do, however, strongly suspect that his understanding of the term "data type" was in terms of physical representations and built-in types only as in languages like Fortran and Cobol.

Does TTM really militate against support for enumerated types?  I don't remember discussing these with Chris.  If it is thought that a special prescription is needed, or some additional text in RM Pre 4, then I can only apologise and plead for liberal interpretation of RM Pre 4.  Tutorial D has no special syntax for such types, but surely an enumeration of a set of values can be coded in a possrep constraint.

What is the typical treatment of enumerated types in strongly-typed languages that support them?  How would Tuesday be denoted as a value of type WEEKDAY?

Hugh

Pascal was the first language where I saw this supported and it went somewhat like

var WEEKDAY myweekdayvar;
myweekdayvar := TUESDAY;

var SUIT mysuitvar := CLUBS;

which illustrates Anthony's remark about internationalisation, because 'TUESDAY' and 'CLUBS' would also be how those values get displayed.

Such values should never be displayed, except perhaps to a developer for debugging purposes.

Sheesh you're being argumentative. Should a DBMS display a Supplier number as 3 to business users? Or should it always display a meaningful name 'Acme Supply Co' ? If Acme deliver on TUESDAY, what should (say) the delivery docket show if not "TUESDAY"? There's plenty of intensive users who prefer numeric codes over verbosity.

I wasn't intentionally being argumentative, only reiterating what I thought was well-established programming best practice: enums shall not leak into the outside world.

Days of the week are a curious example, belonging to the small set of fixed pieces of data that belong -- in many applications -- equally to the computational domain and user domain because the days of the week never change, or at least aren't likely to change in our lifetimes. Names of months are another. Outside of that, not much is so rigid that it justifies exposing enums, which I would argue shouldn't even belong to the set of types that can be stored in the persistent database because of inevitable issues with changing enums (unless they're days of the week or names of months, of course.)

Before everyone rushes to find counterexamples and counterarguments, I should point out that I fully accept that best practices almost invariably have tradeoffs and situations that warrant violating them, which is why they're called "best practices" and not "absolute rules."

What do you mean by "raw enumeration"? Was that a name TUESDAY or the PhysRep 1? I agree the PhysRep should not leak out -- even to developers/debuggers.

What's wrong with a (business) user-visible type being from an enumeration? Are businesses allowed to invent extra days of the week or something 'as time-varying data'? What's the benefit to anybody of insisting on extra machinery to map from enumeration value TUESDAY to String "Tuesday" and back? That's the sort of machinery compilers are really good at and programmers not.

It was a name, an internal error state like MISSING_FOO_ATTRIBUTE_SETTING. Not the sort of thing that your carefully crafted, precisely machined, translated into every human language, tested to the nth degree, Very Expensive Software™ is supposed to emit. It was supposed to emit -- if it ever appeared at all -- a friendly message like, "ERROR #23452: All bar messages must have at least one foo attribute with a value selected from one of zot, zap, faz, baz, bozzle, or a numeric value between 3 and 7 inclusive. Note: Under normal circumstances, this error should not occur and has been logged. Please contact your account support representative regarding Ticket #4095830 unless you're a Premium Plus Extra Ultra+ member, in which case our technical response team is already on their way to your site with a compensatory cheque addressed to your company and a complimentary box of gold-wrapped Hotel Chocolate® treats for each registered member of your development team", and with that correctly translated into the language of your choice.

Yes, I have exaggerated the user-friendly message a bit, but only slightly.

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 March 16, 2020, 5:01 pm

Before everyone rushes to find counterexamples and counterarguments

Spoil-sport ...

Quote from Hugh on March 16, 2020, 11:33 am
Quote from AntC on March 16, 2020, 1:26 am
Quote from Hugh on March 15, 2020, 12:46 pm

Personally I see little point in trying to guess what Codd really meant by "domain".

So please explain how TTM distinguishes supplier 3 from part 3, given that people will give Integer identifiers to pretty much everything. Or should they not do that? Then where does TTM proscribe it?

Surely you know that it has never been an aim of TTM to prescribe or proscribe user behaviour.  UDT support allows users to make such distinctions if they so wish.

Thanks Hugh, maybe not pre/proscribe, but I see in D&D texts some Pretty Strong Suggestions. Take this from DTATRM for a tuple conforming to the Heading of relvar SP

TUP{ S# S#('S3'), P# P#('P3'), QTY 3}

This suffers excessive circumlocution, and I don't mean just the sort of circumlocution that could be hidden by a shorthand (as is usually done in your texts). I mean it suffers redundant information.

  • It's saying Supplier Supplier Supplier 3.
  • It's using a CHAR type, so needing quotes around the value; and meaning potentially Supplier Supplier 'S0003' is distinct from Supplier Supplier 'S3'.
  • If Supplier identifiers are to be numbers, we want their PhysRep to be the same as for Integer, for efficient indexing. That's not saying their UDT is Integer.
  • If we want the number to appear with a letter prefix, to disambiguate where it appears in densely-presented values, that should be in the presentation layer/toString( ) form, and with canonical width, not held in the database in prefixed form.
    (Although surely on a screen or paper we'd put a label or column header 'Supplier' spelled out in full.)

So I want to write program code like

var S# mySupplier;
mySupplier := 3;
mySuppTup = TUP{ mySupplier, P# 3, QTY 3 };

That is:

  • In a syntactic context expecting a supplier number, I should be able to put a numeric literal, not hang it around with duplicate type annotation.
  • Then prefixing a literal with P# or QTY should be sufficient disambiguation.
  • Such a context-disambiguated value should be first-class, assignable to a var, argument to a function invocation, returned from a function, etc.
  • In a context expecting an 'indexed set'/collection, such as TUP{ }, I should be able to put elements of distinct types in any sequence, and expect the compiler to index them by type; and to recognise that this value is in an 'equivalence class' to mySuppTup: TUP{ QTY 3, P# 3, mySupplier }.
  • The compiler should be able to choose an efficient PhysRep for such values (same as Integer for Supplier numbers; vector of Integer for the TUP); and apply type-erasure semantics such that the type-marking is virtual.
  • Although Supplier numbers and Part numbers have the same PhysRep, it shall be type-invalid to write SP WHERE S# = P#; but it shall be type-valid to write SP WHERE S# = 3 -- because there's a disambiguating context.
  • Of course it's unusual for database values to appear as literals in program text. A user keying '3' or '0003' into a box on the screen shall be equivalent to mySupplier := 3. Then toString(mySupplier) might yield S3 or S0003, if that's what the users want.
  • I don't want to make it impossible to get the effect of SP WHERE S# = P# or (SP JOIN P#) WHERE WEIGHT = QTY, but I do want to make the coding sufficiently verbose for the programmer to stop and ask themselves whether they might be doing something daft. (Essentially unwrap the based-on Integers, then use bare Integer comparison.)
  • And I want to make it only mildly verbose to get the effect of BillOfMaterials WHERE ComponentP# = AssemblyP#, on grounds that those two attributes are different roles in the same domain of part number. Codd's 1970 terminology (not 'type') there seems to me exactly appropriate to  describe the business-cum-syntax requirement.
Quote from Dave Voorhis on March 16, 2020, 5:01 pm
Quote from AntC on March 16, 2020, 2:30 am
Quote from Dave Voorhis on March 15, 2020, 8:25 pm
Quote from Erwin on March 15, 2020, 2:24 pm
Quote from Hugh on March 15, 2020, 12:46 pm

Personally I see little point in trying to guess what Codd really meant by "domain".  I do, however, strongly suspect that his understanding of the term "data type" was in terms of physical representations and built-in types only as in languages like Fortran and Cobol.

Does TTM really militate against support for enumerated types?  I don't remember discussing these with Chris.  If it is thought that a special prescription is needed, or some additional text in RM Pre 4, then I can only apologise and plead for liberal interpretation of RM Pre 4.  Tutorial D has no special syntax for such types, but surely an enumeration of a set of values can be coded in a possrep constraint.

What is the typical treatment of enumerated types in strongly-typed languages that support them?  How would Tuesday be denoted as a value of type WEEKDAY?

Hugh

Pascal was the first language where I saw this supported and it went somewhat like

var WEEKDAY myweekdayvar;
myweekdayvar := TUESDAY;

var SUIT mysuitvar := CLUBS;

which illustrates Anthony's remark about internationalisation, because 'TUESDAY' and 'CLUBS' would also be how those values get displayed.

Such values should never be displayed, except perhaps to a developer for debugging purposes.

Sheesh you're being argumentative. Should a DBMS display a Supplier number as 3 to business users? Or should it always display a meaningful name 'Acme Supply Co' ? If Acme deliver on TUESDAY, what should (say) the delivery docket show if not "TUESDAY"? There's plenty of intensive users who prefer numeric codes over verbosity.

I wasn't intentionally being argumentative, only reiterating what I thought was well-established programming best practice: enums shall not leak into the outside world.

Days of the week are a curious example, belonging to the small set of fixed pieces of data that belong -- in many applications -- equally to the computational domain and user domain because the days of the week never change, or at least aren't likely to change in our lifetimes. Names of months are another. Outside of that, not much is so rigid that it justifies exposing enums, which I would argue shouldn't even belong to the set of types that can be stored in the persistent database because of inevitable issues with changing enums (unless they're days of the week or names of months, of course.)

Before everyone rushes to find counterexamples and counterarguments, I should point out that I fully accept that best practices almost invariably have tradeoffs and situations that warrant violating them, which is why they're called "best practices" and not "absolute rules."

What do you mean by "raw enumeration"? Was that a name TUESDAY or the PhysRep 1? I agree the PhysRep should not leak out -- even to developers/debuggers.

What's wrong with a (business) user-visible type being from an enumeration? Are businesses allowed to invent extra days of the week or something 'as time-varying data'? What's the benefit to anybody of insisting on extra machinery to map from enumeration value TUESDAY to String "Tuesday" and back? That's the sort of machinery compilers are really good at and programmers not.

It was a name, an internal error state like MISSING_FOO_ATTRIBUTE_SETTING. Not the sort of thing that your carefully crafted, precisely machined, translated into every human language, tested to the nth degree, Very Expensive Software™ is supposed to emit. It was supposed to emit -- if it ever appeared at all -- a friendly message like, "ERROR #23452: All bar messages must have at least one foo attribute with a value selected from one of zot, zap, faz, baz, bozzle, or a numeric value between 3 and 7 inclusive. Note: Under normal circumstances, this error should not occur and has been logged. Please contact your account support representative regarding Ticket #4095830 unless you're a Premium Plus Extra Ultra+ member, in which case our technical response team is already on their way to your site with a compensatory cheque addressed to your company and a complimentary box of gold-wrapped Hotel Chocolate® treats for each registered member of your development team", and with that correctly translated into the language of your choice.

Yes, I have exaggerated the user-friendly message a bit, but only slightly.

Coercion is deprecated in general.  We certainly wouldn't want to embrace it in the language we use for illustrative purposes.  The idea of the examples you cite is to illustrate possibly useful applications for UDTs.

Hugh

Coauthor of The Third Manifesto and related books.

Thanks Hugh, maybe not pre/proscribe, but I see in D&D texts some Pretty Strong Suggestions. Take this from DTATRM for a tuple conforming to the Heading of relvar SP

TUP{ S# S#('S3'), P# P#('P3'), QTY 3}

So I want to write program code like

var S# mySupplier;
mySupplier := 3;
mySuppTup = TUP{ mySupplier, P# 3, QTY 3 };

That is:

  • In a syntactic context expecting a supplier number, I should be able to put a numeric literal, not hang it around with duplicate type annotation.
  • Then prefixing a literal with P# or QTY should be sufficient disambiguation.

Not in general. In this case P# is ambiguous. Take this case, what do you write for this?

TUP{ S# S#('S3'), parentP# P#('P3'), childP# P#('P3'), childQTY 3}

Did your language definition:

  1. Read 'P#' as an attribute name, '3' as an integer, and supply an implicit conversion to type P# (being the type of attribute P#)?
  2. Read 'P#' as an attribute name, '3' as a value in a specialised context provided by type P# (being the type of attribute P#)?
  3. Read 'P#' as a type name, '3' as an integer, convert the integer to a value of type P# and assign it to attribute P# positionally?

I prefer (a), but others may differ. Implicit non-lossy ('widening') conversions are safe in general, but are not for the purists.

 

Andl - A New Database Language - andl.org
Quote from dandl on March 18, 2020, 12:55 am

Thanks Hugh, maybe not pre/proscribe, but I see in D&D texts some Pretty Strong Suggestions. Take this from DTATRM for a tuple conforming to the Heading of relvar SP

TUP{ S# S#('S3'), P# P#('P3'), QTY 3}

So I want to write program code like

var S# mySupplier;
mySupplier := 3;
mySuppTup = TUP{ mySupplier, P# 3, QTY 3 };

That is:

  • In a syntactic context expecting a supplier number, I should be able to put a numeric literal, not hang it around with duplicate type annotation.
  • Then prefixing a literal with P# or QTY should be sufficient disambiguation.

Not in general. In this case P# is ambiguous.

No I'm rejecting TTM's duplication of both a Selector P#( ) and an attribute name P#. Pick one only. And don't decorate Supplier numbers with letters, unless you want an alphabetic code in which 'P3' /= 'P0003' and Supplier 'P3' is sorted between 'P2999', 'P30'.

Take this case, what do you write for this?

TUP{ S# S#('S3'), parentP# P#('P3'), childP# P#('P3'), childQTY 3}

No I don't want to write that. Triplication.

Did your language definition:

I didn't give any declaration forms, but let me posit these, for the sake of illustration:

DOMAIN S#  Integer;          // same PhysRep as Integer, different Nominative type
DOMAIN QTY Integer;
DOMAIN P#  Integer;

ROLE parentP# P#;           // same PhysRep as P#, em 'comparable' Nominative type
ROLE childP#  P#;

ROLE childQTY QTY;

TUP{ S# 3, parentP# 3, childP# 3, childQTY 3 }

 

  1. Read 'P#' as an attribute name, '3' as an integer, and supply an implicit conversion to type P# (being the type of attribute P#)?
  2. Read 'P#' as an attribute name, '3' as a value in a specialised context provided by type P# (being the type of attribute P#)?
  3. Read 'P#' as a type name, '3' as an integer, convert the integer to a value of type P# and assign it to attribute P# positionally?

I prefer (a), but others may differ. Implicit non-lossy ('widening') conversions are safe in general, but are not for the purists.

 

No I don't see any coercions here. I can say that because to the extent I can emulate this in Haskell, also there's no coercions. I'm using the sort of modern type theory Dave wanted me to use; but I fear nobody round here is actually up with the play. So round here you want to both reject the old stuff (Codd 1970) and ignore the new stuff (not actually new: polymorphism/overloading is in Strachey 1967, brought up to date in the ML family of language from 1980's, specifically Wadler 1989). I say that because I explained all this before and it fell on deaf ears.

Firstly let me reiterate that it's unusual to express values to be put in the database as literals in a program. Usually values come in from the database or from screen entry as already of the appropriate type. To make stark that this is not coercion, this is type-invalid:

var Integer threeInt;
threeInt := 3;              // accepted, not a coercion

var S# mySupplier;
mySupplier := threeInt;     // rejected type mis-match
mySupplier := 3;            // accepted, not a coercion

How does that work? Program token appearing as 3 is not Integer 3 in the FORTRAN/ALGOL/PL/1 sense. (It actually should be understandable as denoting an object with access methods in the OOP sense.) It's shorthand for a polymorphic expression fromInteger(#3), where #3 denotes the PhysRep for Integer 3, and fromInteger( ) is a built-in access method (compare toString( ), fromString( )). Perhaps you might even write it #3.fromInteger.

fromInteger( ) is polymorphic/overloaded. It's a method that takes an argument of type Integer, and returns a result of the type demanded by its program context -- i.e. the overloading. (For example, the context might demand a ShortInt or a Float or a Rational.) In cases where the context is demanding a Nominative type (DOMAIN declaration) based on Integer -- i.e. with same PhysRep as Integer, that's a no-op whose only purpose is to make the types match up.

mySupplier := threeInt; is a type mis-match because the earlier assignment to threeInt has already 'executed' the no-op fromInteger(#3), so threeInt is not polymorphic. Of course the compiler, after inferring the type of the context, should 'execute' the fromInteger( ) at compile time; so there's no run-time cost here.

Quote from Hugh on March 17, 2020, 11:30 am
Quote from Dave Voorhis on March 16, 2020, 5:01 pm
Quote from AntC on March 16, 2020, 2:30 am
Quote from Dave Voorhis on March 15, 2020, 8:25 pm
Quote from Erwin on March 15, 2020, 2:24 pm
Quote from Hugh on March 15, 2020, 12:46 pm

Personally I see little point in trying to guess what Codd really meant by "domain".  I do, however, strongly suspect that his understanding of the term "data type" was in terms of physical representations and built-in types only as in languages like Fortran and Cobol.

Does TTM really militate against support for enumerated types?  I don't remember discussing these with Chris.  If it is thought that a special prescription is needed, or some additional text in RM Pre 4, then I can only apologise and plead for liberal interpretation of RM Pre 4.  Tutorial D has no special syntax for such types, but surely an enumeration of a set of values can be coded in a possrep constraint.

What is the typical treatment of enumerated types in strongly-typed languages that support them?  How would Tuesday be denoted as a value of type WEEKDAY?

Hugh

...

...

...

...

Coercion is deprecated in general.  We certainly wouldn't want to embrace it in the language we use for illustrative purposes.  The idea of the examples you cite is to illustrate possibly useful applications for UDTs.

Hi Hugh, I think yours is replying to a different message, from me March 17, 2020, 6:43 am. Then see my reply just now to David.

I see no coercions here. Those DTATRM examples illustrate what I would call obfuscated applications for UDTs that would be off-putting to most programmers. I want something that has much stronger type safety than SQL, but much less circumlocution than Tutorial D.

Addit: What I'm doing is I think licensed by RM Pre 4 b.:

If T is system defined, then zero or more possible representations for values of type T shall be declared and thus made visible in D.

Note the "zero". There is a PhysRep for system-defined Integer; but there are zero PossReps visible in the D. The form #3 is the internal 'storage structure definition language'.

BTW RM Pre 4 b. seems to be at variance with the first paragraph of RM Pre 4.

... (at least one [PossRep], because there is obviously always one that is the same as the physical representation).

I'm saying there's zero PossReps same as the PhysRep, for numeric literals. There is not "always" such a PossRep; neither is it "obvious" why there must be.

I guess in terms of RM Pre 4 a., program token bare 3 is a Selector. But it takes no parameters (contra RM Pre 4 a. 1.) or perhaps it is both Selector and parameter rolled together. I am conforming to RM Pre 4 a. 2.: every value of type Integer is producible from some invocation of a pseudo-literal.

Quote from AntC on March 18, 2020, 4:49 am
Quote from dandl on March 18, 2020, 12:55 am

Thanks Hugh, maybe not pre/proscribe, but I see in D&D texts some Pretty Strong Suggestions. Take this from DTATRM for a tuple conforming to the Heading of relvar SP

TUP{ S# S#('S3'), P# P#('P3'), QTY 3}

So I want to write program code like

var S# mySupplier;
mySupplier := 3;
mySuppTup = TUP{ mySupplier, P# 3, QTY 3 };

That is:

  • In a syntactic context expecting a supplier number, I should be able to put a numeric literal, not hang it around with duplicate type annotation.
  • Then prefixing a literal with P# or QTY should be sufficient disambiguation.

Not in general. In this case P# is ambiguous.

No I'm rejecting TTM's duplication of both a Selector P#( ) and an attribute name P#. Pick one only. And don't decorate Supplier numbers with letters, unless you want an alphabetic code in which 'P3' /= 'P0003' and Supplier 'P3' is sorted between 'P2999', 'P30'.

Take this case, what do you write for this?

TUP{ S# S#('S3'), parentP# P#('P3'), childP# P#('P3'), childQTY 3}

No I don't want to write that. Triplication.

Did your language definition:

I didn't give any declaration forms, but let me posit these, for the sake of illustration:

DOMAIN S#  Integer;          // same PhysRep as Integer, different Nominative type
DOMAIN QTY Integer;
DOMAIN P#  Integer;

ROLE parentP# P#;           // same PhysRep as P#, em 'comparable' Nominative type
ROLE childP#  P#;

ROLE childQTY QTY;

TUP{ S# 3, parentP# 3, childP# 3, childQTY 3 }

 

  1. Read 'P#' as an attribute name, '3' as an integer, and supply an implicit conversion to type P# (being the type of attribute P#)?
  2. Read 'P#' as an attribute name, '3' as a value in a specialised context provided by type P# (being the type of attribute P#)?
  3. Read 'P#' as a type name, '3' as an integer, convert the integer to a value of type P# and assign it to attribute P# positionally?

I prefer (a), but others may differ. Implicit non-lossy ('widening') conversions are safe in general, but are not for the purists.

 

No I don't see any coercions here. I can say that because to the extent I can emulate this in Haskell, also there's no coercions. I'm using the sort of modern type theory Dave wanted me to use; but I fear nobody round here is actually up with the play. So round here you want to both reject the old stuff (Codd 1970) and ignore the new stuff (not actually new: polymorphism/overloading is in Strachey 1967, brought up to date in the ML family of language from 1980's, specifically Wadler 1989). I say that because I explained all this before and it fell on deaf ears.

Firstly let me reiterate that it's unusual to express values to be put in the database as literals in a program. Usually values come in from the database or from screen entry as already of the appropriate type. To make stark that this is not coercion, this is type-invalid:

var Integer threeInt;
threeInt := 3;              // accepted, not a coercion

var S# mySupplier;
mySupplier := threeInt;     // rejected type mis-match
mySupplier := 3;            // accepted, not a coercion

How does that work? Program token appearing as 3 is not Integer 3 in the FORTRAN/ALGOL/PL/1 sense. (It actually should be understandable as denoting an object with access methods in the OOP sense.) It's shorthand for a polymorphic expression fromInteger(#3), where #3 denotes the PhysRep for Integer 3, and fromInteger( ) is a built-in access method (compare toString( ), fromString( )). Perhaps you might even write it #3.fromInteger.

fromInteger( ) is polymorphic/overloaded. It's a method that takes an argument of type Integer, and returns a result of the type demanded by its program context -- i.e. the overloading. (For example, the context might demand a ShortInt or a Float or a Rational.) In cases where the context is demanding a Nominative type (DOMAIN declaration) based on Integer -- i.e. with same PhysRep as Integer, that's a no-op whose only purpose is to make the types match up.

mySupplier := threeInt; is a type mis-match because the earlier assignment to threeInt has already 'executed' the no-op fromInteger(#3), so threeInt is not polymorphic. Of course the compiler, after inferring the type of the context, should 'execute' the fromInteger( ) at compile time; so there's no run-time cost here.

If I understand correctly, a domain is a UDT and an attribute whose name is a domain name, or the name of a role, has that domain, or the domain on which that role is defined, as its type.

No doubt such schemes can be made to work but my objection to them has always been the care that is needed to specify attribute names to avoid unsuspected clashes.   In TD tup{x 1} denotes a tuple whose attribute x is of type integer (equivalent to tup{x int}{x 1}).  It won't work as desired if a domain or role x is already defined.  Conversely, DOMAIN x char won't work if the database already has x used for an attribute somewhere, and it doesn't even have to be for an attribute in a base or virtual relvar -- it could be in some expression used in an operator or virtual relvar definition, for example.  Does that objection apply here?  Or am I missing something?

Hugh

Coauthor of The Third Manifesto and related books.

How does that work? Program token appearing as 3 is not Integer 3 in the FORTRAN/ALGOL/PL/1 sense. (It actually should be understandable as denoting an object with access methods in the OOP sense.) It's shorthand for a polymorphic expression fromInteger(#3), where #3 denotes the PhysRep for Integer 3, and fromInteger( ) is a built-in access method (compare toString( ), fromString( )). Perhaps you might even write it #3.fromInteger.

fromInteger( ) is polymorphic/overloaded. It's a method that takes an argument of type Integer, and returns a result of the type demanded by its program context -- i.e. the overloading. (For example, the context might demand a ShortInt or a Float or a Rational.) In cases where the context is demanding a Nominative type (DOMAIN declaration) based on Integer -- i.e. with same PhysRep as Integer, that's a no-op whose only purpose is to make the types match up.

mySupplier := threeInt; is a type mis-match because the earlier assignment to threeInt has already 'executed' the no-op fromInteger(#3), so threeInt is not polymorphic. Of course the compiler, after inferring the type of the context, should 'execute' the fromInteger( ) at compile time; so there's no run-time cost here.

I came up with a slightly different approach. Think of S# 3 as a shorthand for  S# := typeof(S#)(3). In other words, the value of the attribute S# is provided by a selector invocation of  the type of S#. You don't have to agonise over the type of lexeme '3', the selector accepts an integer value as its argument. And there can be an overload: S# := typeof(S#)('3').

But please note that standard syntax in C#/Java looks more like new Supplier(3, 3, 3). There is no obvious reason why a D should not look like any modern programming language and be built on whatever record syntax it provides, and whatever level of wordiness it imposes. Rather than imposing an entirely new esoteric type system, just find a nice way to add RA operators to an existing language. But that's another topic.

Andl - A New Database Language - andl.org
Quote from AntC on March 18, 2020, 4:56 am

 

Addit: What I'm doing is I think licensed by RM Pre 4 b.:

If T is system defined, then zero or more possible representations for values of type T shall be declared and thus made visible in D.

Note the "zero". There is a PhysRep for system-defined Integer; but there are zero PossReps visible in the D. The form #3 is the internal 'storage structure definition language'.

I've always found that "zero possrep" stuff misses a point that should in fact be blatantly obvious : that every type must not only always have a physrep, but also a possrep that has a single CHAR component.

And it is this very possrep that the compiler uses to parse the text string "3" where it appears as a literal (and where from context it is clear that it is supposed to represent an integer) and return the corresponding integer value.

Or put otherwise : the function performed by the compiler is exactly the same function as the one implemented in the corresponding value-selector function implied by the possrep.  And the function performed by the runtime system to render the value on an output device such as a display, is exactly the same function as the "getter" function implied by the possrep.