The missing tuple
Quote from dandl on September 8, 2019, 1:38 amIt occurs to me that TD/Rel does not natively have the kind of list or tuple found in several other languages.
TD defines
- A named tuple (a set of values of different types, identified by name)
- An unnamed relation (set of unnamed tuples)
- An array (ordered list of values of the same type, identified by position)
- Simple scalars
It does not have an unnamed tuple/list (list of values of different types, identified by position). You may not need it often, but when you need it nothing else will do.
You could probably construct one for known types using the IM, and you can fake it with a two column relation, which would be enough in many cases, I guess.
It occurs to me that TD/Rel does not natively have the kind of list or tuple found in several other languages.
TD defines
- A named tuple (a set of values of different types, identified by name)
- An unnamed relation (set of unnamed tuples)
- An array (ordered list of values of the same type, identified by position)
- Simple scalars
It does not have an unnamed tuple/list (list of values of different types, identified by position). You may not need it often, but when you need it nothing else will do.
You could probably construct one for known types using the IM, and you can fake it with a two column relation, which would be enough in many cases, I guess.
Quote from Darren Duncan on September 8, 2019, 3:25 amQuote from dandl on September 8, 2019, 1:38 amIt occurs to me that TD/Rel does not natively have the kind of list or tuple found in several other languages.
It does not have an unnamed tuple/list (list of values of different types, identified by position). You may not need it often, but when you need it nothing else will do.
Yeah, I solved that problem a long time ago. My solution is to fake an ordered tuple in terms of a named tuple where the ordinal position is represented by a single character name whose Unicode code point is the ordinal position. So for example the tuple (29,95) is represented as ("\c0":29,"\c1":95). Since the first 32 Unicode code points are non-printing control characters, these names would be distinct from any normal attribute names up to an ordered tuple of degree 32, which should handle all common cases. This scheme also allows easy mixing of ordered and named attributes in the same tuple.
Quote from dandl on September 8, 2019, 1:38 amIt occurs to me that TD/Rel does not natively have the kind of list or tuple found in several other languages.
It does not have an unnamed tuple/list (list of values of different types, identified by position). You may not need it often, but when you need it nothing else will do.
Yeah, I solved that problem a long time ago. My solution is to fake an ordered tuple in terms of a named tuple where the ordinal position is represented by a single character name whose Unicode code point is the ordinal position. So for example the tuple (29,95) is represented as ("\c0":29,"\c1":95). Since the first 32 Unicode code points are non-printing control characters, these names would be distinct from any normal attribute names up to an ordered tuple of degree 32, which should handle all common cases. This scheme also allows easy mixing of ordered and named attributes in the same tuple.
Quote from AntC on September 8, 2019, 6:29 amQuote from dandl on September 8, 2019, 1:38 amIt occurs to me that TD/Rel does not natively have the kind of list or tuple found in several other languages.
Em? Lists found in other languages are not the same as tuples found in other languages. So are you here trying to talk about both? Or only one -- then which?
Lists can be achieved under TTM's Inheritance Model, using a recursive user-defined type. (Using the by now familiar trick of simulating a Tagged Union.) Or possibly using an RVA, depending on whether the sequence within the list represents information, or is just a serialisation mechanism.
TD defines
- A named tuple (a set of values of different types, identified by name)
- An unnamed relation (set of unnamed tuples)
- An array (ordered list of values of the same type, identified by position)
- Simple scalars
It does not have an unnamed tuple/list (list of values of different types, identified by position). You may not need it often, but when you need it nothing else will do.
Do you mean a List (arbitrary cardinality, recursively defined); or a tuple (aka 'sequence' in maths, not recursive but 'flat', each degree of which is a distinct
typesort)?When/why do you need "... values of different types, identified by position"? TTM-defined tuples have potentially-different attribute types, identified by attribute name. I suppose you could name the positions
A1, A2, A3, ...
. As an aside, Childs discusses representations using Integers as (in effect) attribute names.The only time I can imagine you might need them is mapping from/to some non-TTM data representation which identifies only by position. (CSV or some such -- even XML/JSON uses tags. Note those use String as the 'universal data format'; and Tutorial D (or at least Rel) includes String manipulation operations. For those formats, potentially they represent sets-of-tuples only by position, but if they're sets, position doesn't matter.)
The Relational Model provides perfectly general means to represent structured data, building on set theory. Elements of a set don't have 'position' or sequence. If you have some representation that relies on position/sequence to express structure, that can always be mapped 1:1 to some representation within the RM.
Or you don't have structured data. Then don't use Tutorial D or the RM until you do.
Quote from dandl on September 8, 2019, 1:38 amIt occurs to me that TD/Rel does not natively have the kind of list or tuple found in several other languages.
Em? Lists found in other languages are not the same as tuples found in other languages. So are you here trying to talk about both? Or only one -- then which?
Lists can be achieved under TTM's Inheritance Model, using a recursive user-defined type. (Using the by now familiar trick of simulating a Tagged Union.) Or possibly using an RVA, depending on whether the sequence within the list represents information, or is just a serialisation mechanism.
TD defines
- A named tuple (a set of values of different types, identified by name)
- An unnamed relation (set of unnamed tuples)
- An array (ordered list of values of the same type, identified by position)
- Simple scalars
It does not have an unnamed tuple/list (list of values of different types, identified by position). You may not need it often, but when you need it nothing else will do.
Do you mean a List (arbitrary cardinality, recursively defined); or a tuple (aka 'sequence' in maths, not recursive but 'flat', each degree of which is a distinct typesort)?
When/why do you need "... values of different types, identified by position"? TTM-defined tuples have potentially-different attribute types, identified by attribute name. I suppose you could name the positions A1, A2, A3, ...
. As an aside, Childs discusses representations using Integers as (in effect) attribute names.
The only time I can imagine you might need them is mapping from/to some non-TTM data representation which identifies only by position. (CSV or some such -- even XML/JSON uses tags. Note those use String as the 'universal data format'; and Tutorial D (or at least Rel) includes String manipulation operations. For those formats, potentially they represent sets-of-tuples only by position, but if they're sets, position doesn't matter.)
The Relational Model provides perfectly general means to represent structured data, building on set theory. Elements of a set don't have 'position' or sequence. If you have some representation that relies on position/sequence to express structure, that can always be mapped 1:1 to some representation within the RM.
Or you don't have structured data. Then don't use Tutorial D or the RM until you do.
Quote from johnwcowan on September 8, 2019, 1:40 pmQuote from dandl on September 8, 2019, 1:38 amIt does not have an unnamed tuple/list (list of values of different types, identified by position). You may not need it often, but when you need it nothing else will do.
I don't understand how such a thing would work in a statically typed language. Let T be a tuple of type (Float, Int, String). Then T[0] or T[2] have statically decidable types, but what is the type of T[i]? The most you can say is that it is Union(Float, Int, String), which is not very useful.
Of course you can use any of the tricks described above. But then the tuple subscript is only a nominal scale, not cardinal.
Quote from dandl on September 8, 2019, 1:38 amIt does not have an unnamed tuple/list (list of values of different types, identified by position). You may not need it often, but when you need it nothing else will do.
I don't understand how such a thing would work in a statically typed language. Let T be a tuple of type (Float, Int, String). Then T[0] or T[2] have statically decidable types, but what is the type of T[i]? The most you can say is that it is Union(Float, Int, String), which is not very useful.
Of course you can use any of the tricks described above. But then the tuple subscript is only a nominal scale, not cardinal.
Quote from Dave Voorhis on September 8, 2019, 3:05 pmQuote from johnwcowan on September 8, 2019, 1:40 pmQuote from dandl on September 8, 2019, 1:38 amIt does not have an unnamed tuple/list (list of values of different types, identified by position). You may not need it often, but when you need it nothing else will do.
I don't understand how such a thing would work in a statically typed language. Let T be a tuple of type (Float, Int, String). Then T[0] or T[2] have statically decidable types, but what is the type of T[i]? The most you can say is that it is Union(Float, Int, String), which is not very useful.
In Tutorial D, using the IM, it's not ideal from a production language point of view but for tutorial purposes it's certainly workable and is sufficient to illustrate the idea. Some extensions to Tutorial D (e.g., pattern matching) would make it more palatable. I'm travelling at the moment or I'd conjure up an example, but the mailing list archives have examples from when this was discussed before.
Quote from johnwcowan on September 8, 2019, 1:40 pmQuote from dandl on September 8, 2019, 1:38 amIt does not have an unnamed tuple/list (list of values of different types, identified by position). You may not need it often, but when you need it nothing else will do.
I don't understand how such a thing would work in a statically typed language. Let T be a tuple of type (Float, Int, String). Then T[0] or T[2] have statically decidable types, but what is the type of T[i]? The most you can say is that it is Union(Float, Int, String), which is not very useful.
In Tutorial D, using the IM, it's not ideal from a production language point of view but for tutorial purposes it's certainly workable and is sufficient to illustrate the idea. Some extensions to Tutorial D (e.g., pattern matching) would make it more palatable. I'm travelling at the moment or I'd conjure up an example, but the mailing list archives have examples from when this was discussed before.
Quote from Darren Duncan on September 8, 2019, 10:54 pmQuote from dandl on September 8, 2019, 1:38 amIt does not have an unnamed tuple/list (list of values of different types, identified by position). You may not need it often, but when you need it nothing else will do.
I think you would need it often. Since Tutorial D has positional rather than named operator arguments, a tuple whose attributes are identified by position is very important. The type of the argument list of an operator as a whole is that kind of tuple.
Quote from dandl on September 8, 2019, 1:38 amIt does not have an unnamed tuple/list (list of values of different types, identified by position). You may not need it often, but when you need it nothing else will do.
I think you would need it often. Since Tutorial D has positional rather than named operator arguments, a tuple whose attributes are identified by position is very important. The type of the argument list of an operator as a whole is that kind of tuple.
Quote from Darren Duncan on September 8, 2019, 10:59 pmQuote from johnwcowan on September 8, 2019, 1:40 pmQuote from dandl on September 8, 2019, 1:38 amIt does not have an unnamed tuple/list (list of values of different types, identified by position). You may not need it often, but when you need it nothing else will do.
I don't understand how such a thing would work in a statically typed language. Let T be a tuple of type (Float, Int, String). Then T[0] or T[2] have statically decidable types, but what is the type of T[i]? The most you can say is that it is Union(Float, Int, String), which is not very useful.
There is no problem here. How such a thing would work is exactly the same as how it works in Tutorial D now. When T is a tuple of type (x Float, y Int, z String) you don't have any problem determining the types of any attribute. Likewise, when T is a type of type (0 Float, 1 Int, 2 String) you would also have no problem. Whatever generic operators work for x,y,z would work the same for 0,1,2 identifiers. Just as you say "x from t" you say "0 from t". The signature of "from" is the same either way. Works perfectly well in a statically typed language.
Quote from johnwcowan on September 8, 2019, 1:40 pmQuote from dandl on September 8, 2019, 1:38 amIt does not have an unnamed tuple/list (list of values of different types, identified by position). You may not need it often, but when you need it nothing else will do.
I don't understand how such a thing would work in a statically typed language. Let T be a tuple of type (Float, Int, String). Then T[0] or T[2] have statically decidable types, but what is the type of T[i]? The most you can say is that it is Union(Float, Int, String), which is not very useful.
There is no problem here. How such a thing would work is exactly the same as how it works in Tutorial D now. When T is a tuple of type (x Float, y Int, z String) you don't have any problem determining the types of any attribute. Likewise, when T is a type of type (0 Float, 1 Int, 2 String) you would also have no problem. Whatever generic operators work for x,y,z would work the same for 0,1,2 identifiers. Just as you say "x from t" you say "0 from t". The signature of "from" is the same either way. Works perfectly well in a statically typed language.
Quote from Dave Voorhis on September 8, 2019, 11:07 pmQuote from Darren Duncan on September 8, 2019, 10:54 pmQuote from dandl on September 8, 2019, 1:38 amIt does not have an unnamed tuple/list (list of values of different types, identified by position). You may not need it often, but when you need it nothing else will do.
I think you would need it often. Since Tutorial D has positional rather than named operator arguments, a tuple whose attributes are identified by position is very important. The type of the argument list of an operator as a whole is that kind of tuple.
You'd only need it often if you've defined operator argument/parameter lists to belong to the type of "unnamed tuple/list".
If you haven't defined it in that manner, I don't think you'd need it often if at all. I've been writing Tutorial D code to do real things for years, and have not yet come across a need for it.
Quote from Darren Duncan on September 8, 2019, 10:54 pmQuote from dandl on September 8, 2019, 1:38 amIt does not have an unnamed tuple/list (list of values of different types, identified by position). You may not need it often, but when you need it nothing else will do.
I think you would need it often. Since Tutorial D has positional rather than named operator arguments, a tuple whose attributes are identified by position is very important. The type of the argument list of an operator as a whole is that kind of tuple.
You'd only need it often if you've defined operator argument/parameter lists to belong to the type of "unnamed tuple/list".
If you haven't defined it in that manner, I don't think you'd need it often if at all. I've been writing Tutorial D code to do real things for years, and have not yet come across a need for it.
Quote from Dave Voorhis on September 8, 2019, 11:14 pmQuote from Darren Duncan on September 8, 2019, 10:59 pmQuote from johnwcowan on September 8, 2019, 1:40 pmQuote from dandl on September 8, 2019, 1:38 amIt does not have an unnamed tuple/list (list of values of different types, identified by position). You may not need it often, but when you need it nothing else will do.
I don't understand how such a thing would work in a statically typed language. Let T be a tuple of type (Float, Int, String). Then T[0] or T[2] have statically decidable types, but what is the type of T[i]? The most you can say is that it is Union(Float, Int, String), which is not very useful.
There is no problem here. How such a thing would work is exactly the same as how it works in Tutorial D now. When T is a tuple of type (x Float, y Int, z String) you don't have any problem determining the types of any attribute. Likewise, when T is a type of type (0 Float, 1 Int, 2 String) you would also have no problem. Whatever generic operators work for x,y,z would work the same for 0,1,2 identifiers. Just as you say "x from t" you say "0 from t". The signature of "from" is the same either way. Works perfectly well in a statically typed language.
Let n FROM T be a feature of the language, where n is an integer reference to the nth attribute of T. Let RAND() return a random integer. Evaluate the expression RAND() FROM T. What is the type of the expression?
This can be handled statically by pattern matching, where (for example) an expression like RAND() from T may only be used within a case statement with options for each possible type. E.g.:
CASE RAND() FROM T WHERE INT: ... WHERE RATIONAL: ... WHERE CHAR: ... OTHERWISE: ... END
Quote from Darren Duncan on September 8, 2019, 10:59 pmQuote from johnwcowan on September 8, 2019, 1:40 pmQuote from dandl on September 8, 2019, 1:38 amIt does not have an unnamed tuple/list (list of values of different types, identified by position). You may not need it often, but when you need it nothing else will do.
I don't understand how such a thing would work in a statically typed language. Let T be a tuple of type (Float, Int, String). Then T[0] or T[2] have statically decidable types, but what is the type of T[i]? The most you can say is that it is Union(Float, Int, String), which is not very useful.
There is no problem here. How such a thing would work is exactly the same as how it works in Tutorial D now. When T is a tuple of type (x Float, y Int, z String) you don't have any problem determining the types of any attribute. Likewise, when T is a type of type (0 Float, 1 Int, 2 String) you would also have no problem. Whatever generic operators work for x,y,z would work the same for 0,1,2 identifiers. Just as you say "x from t" you say "0 from t". The signature of "from" is the same either way. Works perfectly well in a statically typed language.
Let n FROM T be a feature of the language, where n is an integer reference to the nth attribute of T. Let RAND() return a random integer. Evaluate the expression RAND() FROM T. What is the type of the expression?
This can be handled statically by pattern matching, where (for example) an expression like RAND() from T may only be used within a case statement with options for each possible type. E.g.:
CASE RAND() FROM T WHERE INT: ... WHERE RATIONAL: ... WHERE CHAR: ... OTHERWISE: ... END
Quote from johnwcowan on September 8, 2019, 11:17 pmQuote from Darren Duncan on September 8, 2019, 10:54 pmI think you would need it often. Since Tutorial D has positional rather than named operator arguments,
Yes, but the positions are again merely nominal. You cannot refer to the nth argument of a TD operator, where n is a variable. If TD had mandatory keyword arguments, nothing would change except that you could list them in any order desired, as in Python or Common Lisp, and the argument-tuple would be a regular TTM named tuple.
Quote from Darren Duncan on September 8, 2019, 10:54 pm
I think you would need it often. Since Tutorial D has positional rather than named operator arguments,
Yes, but the positions are again merely nominal. You cannot refer to the nth argument of a TD operator, where n is a variable. If TD had mandatory keyword arguments, nothing would change except that you could list them in any order desired, as in Python or Common Lisp, and the argument-tuple would be a regular TTM named tuple.