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

Reply via email to