On 10/7/10 7:09 CDT, bearophile wrote:
In the two threads (that are a single thread) most of the things I've seen are
bad/wrong.
I have discussed about Tuples several times in the D newsgroup and in Bugzilla.
Please don't ignore all my work.
Before designing tuple syntax you must decide what the purpose of D tuples is.
Then you have to solve the design problems, and avoid all (or most) corner
cases. In this discussion it's useful to have a certain experience of languages
that use tuples often, as Python and others.
Good point.
Tuples have some purposes:
- Python, Go and other languages show that it's handy to allow functions to
return multiple values, this means a tuple.
- A handy tuple unpacking is useful at the calling point of a function that
returns multiple return values.
- Tuples are also useful as quick-and-dirty structs, to sort items in a
different order, etc.
It's useful to use [] to access tuple items, to slice tuples, concat them. It's
useful for tuples to have a good textual representation, to be comparable
lexicographically and to be hashable.
Yes, excellent. Now I realize we don't have hash for tuples just yet.
Another design decision is if tuples have a nominative or structural type, this
problem comes out in this bug report:
http://d.puremagic.com/issues/show_bug.cgi?id=4128
In my opinion it's good for a built-in D tuple to be a structural type. This
also means you are allowed to perform an == among two tuples of different
length (the result is known statically to be always false). I assume that D
tuples know their length at compile-time.
Yah, I think tuples are the quintessential structural types. I think,
however, that "==" shouldn't test for prefix (that would be
_sub_typing). This is because slicing takes care of it. For example:
Tuple!(int, int, int) point3d;
Tuple!(int, int) point2d;
point2d == point3d; // doesn't compile
point2d == point3d[0 .. point2d.length]; // compiles
Another significant problem is about naming things, currently the situation is
a mess:
http://www.digitalmars.com/d/archives/digitalmars/D/Tuple_TypeTuple_tupleof_etc_113005.html
http://d.puremagic.com/issues/show_bug.cgi?id=4113
In the end I have suggested to name "record" the typecons tuples, and "tuple"
the typetuples.
I think we're in good shape with Tuple and tuple. The "other" tuples
deserve an odder name.
I have several bug reports and enhancement requests about tuples, please take
them into account:
http://d.puremagic.com/issues/show_bug.cgi?id=4577
http://d.puremagic.com/issues/show_bug.cgi?id=4582
http://d.puremagic.com/issues/show_bug.cgi?id=4591
http://d.puremagic.com/issues/show_bug.cgi?id=4666
http://d.puremagic.com/issues/show_bug.cgi?id=4846
Nice. I like at least some of each.
Walter:
A lot of it foundered on what the syntax for tuple literals should be. The top
of the list is simply enclosing them in ( ).
This is a bad idea. It has caused troubles in Python because of the singleton
syntax (tuple with 1 item).
During our conversation I conveyed my suspicion that that one corner
case (which is very often encountered in generic code) will inevitably
do this whole thing in, but he was quick to gloss over the issues. I'd
be glad to have experience with Python save us some sweat. Do you have
any links to discussions regarding the matter?
One solution is to use a special unambigous delimiter to denote tuples, like (a
similar solution is used in the Fortress language):
(||)
(|1|)
(|1, 2|)
(|1, 2, 3|)
(|1, 2, 3, 4|)
Yup, the banana notation.
Otherwise a good solution is to use a name:
record()
record(1)
record(1, 2)
record(1, 2, 3)
record(1, 2, 3, 4)
I prefer the record() solution, but the first solution too acceptable.
How about the shorter "tuple"? Wait, it's already there :o).
Finally, I got to thinking, why not just make it a special case:
( ) == tuple
(a) == parenthesized expression
This is not acceptable. No special cases, please. D has already a ton of
special cases.
Python solves this with the (1,) syntax, but it's not nice, it's error-prone,
and it confuses newbies.
Evidence please?
If expr represents a tuple, we (Andrei and I) were thinking about the syntax:
auto (a, b, c, d) = expr;
On this topic I have this enhancement request:
http://d.puremagic.com/issues/show_bug.cgi?id=4579
The Lithpers among you will notice that this essentially provides a handy
car,cdr shortcut for tuples and arrays:
auto (car, cdr) = expr;
This is bad, it's not explicit enough. If you want to support this semantics then the
syntax has to show what you mean. Python uses a * to denote "grab the whole
tail". In D you may use something else, others have suggested tree points, this
works with dynamic arrays too:
auto (car, cdr...) = expr;
Nice.
Regarding field names for tuples, I have used Python and I like the optional
names of D tuples (records). In some situations you don't need names, but in
other situations field names are handy and help avoid bugs. In Python code that
processes and uses tuples contains too many [0] [1] [2] etc that aren't
readable and are bug-prone.
Evidence please?
But a good management of such names asks for the names to not change the type
of the tuple, this is why I talk about structural typing for records.
Makes sense.
Andrei