October 21, 2009
Wed, 21 Oct 2009 16:54:22 +0000, language_fan thusly wrote:

> Wed, 21 Oct 2009 10:48:34 -0500, Andrei Alexandrescu thusly wrote:
> 
>> language_fan wrote:
>>> Wed, 21 Oct 2009 11:07:29 -0400, Robert Jacques thusly wrote:
>>>> My issue was that all your example _showed_ was nominal typing. Though I didn't mention it by name, I did mention that if SOL tuples had structural typing, it might would be a different story. (Well, until/if opImplicitCast was implemented, as it would allow for structural typing.)
>>> 
>>> Why do you insist on using nominal typing for tuples and the library defined "literal". If I want plain old tuples without any kind of type name, why should I care about extra hand waving needed to make it work.
>> 
>> I'm late in this dialog, but I'm not seeing an impediment here. What does it matter to you that tuples actually have a name vs. not having a name at all?
> 
> Using tuples in D is a major pain in the ass. In fact it has been made so hard that people start avoiding the feature like plague. I wrote some test code to reveal how inconsistent their semantics are. Note that you need the built-in tuples for some stuff, like assigning and mixed value/ type tuples. Stuples can only be used as values and when the auto- flattening is not desired.
> 
>>>> STARTS HERE

Even though not being an expert in Python (have not really used it), as an experiment I managed to successfully port the examples in 2 minutes without any kind of problems.

a = (1,1)
e1 = a[0]

print a

def retTest():
  return (1,1)

(d,e) = (10,20)

(d,_) = (10,20)

(d,b) = (1, retTest())

a3b = [ (1,1), (2,2) ]

a7 = { (1,1) : 5 }

a8 = { 5 : (1,1)}

October 21, 2009
Wed, 21 Oct 2009 12:35:35 -0500, Andrei Alexandrescu thusly wrote:

> language_fan wrote:
>> void main() {
>>   Tuple!(int,int) a; // typeof(this) *is* the official tuple type
>>   STuple!(int,int) b;  // this is actually a struct
>> 
>>   a = Tuple!(1,1);  // ok
> 
> That doesn't work for me at all (with std.typecons.Tuple). I think there
> is confusion about a couple of things. One is that Tuple!(int, int) is a
> type that contains two ints, whereas Tuple!(1, 1) is a type that
> contains two compile-time integral values. So if you write:
> 
> a = Tuple!(1, 1);
> 
> that is as good syntactically as:
> 
> a = int;

It might be if we use your definition of tuple. But the mighty compiler dmd 2.035 himself calls my types constructed with my template

>> template Tuple(T...) { alias T Tuple; }

a tuple. How do you explain that? If the resulting type is tuple according to dmd, why do you think it is actually not.

If it works like you say, why does this work then?

>>  Tuple!(int,int) a;
>>  a = Tuple!(12,13);

Here 'a' has a real runtime type (int,int) which is a runtime tuple according to dmd. And I assign a value to the tuple on runtime. I can even test it by printing the values a[0] and a[1] with writefln. So why didn't you just fix this particular tuple type and why did you come up with a library level hack?

Show me a better way to achieve this with your tuple system.

>>  int d,e;
>>  Tuple!(d,e) = Tuple!(10,20);

It's still not clear to me why you don't want to add full syntactic support for built-in tuples. Do you somehow find this kind of code difficult to read or maintain?

(int,int) a = (1,1);
int e1 = a[0];

writefln(a);

(int,int) retTest() { return (1,1); }

int d,e;

(d,e) = (10,20);

(d,_) = (10,20);

(int,int) b;
(d,b) = (1, retTest());

auto a3b = [ (1,1), (2,2) ];

auto a7 = [ (1,1) : 5 ];

auto a8 = [ 5 : (1,1)];

I want to know what is the rationale behind not accepting this semantics that is so widely used in other languages (and I very well mean the languages that *have* built-in tuple types).
October 21, 2009
language_fan, el 21 de octubre a las 17:52 me escribiste:
> Wed, 21 Oct 2009 16:54:22 +0000, language_fan thusly wrote:
> 
> > Wed, 21 Oct 2009 10:48:34 -0500, Andrei Alexandrescu thusly wrote:
> > 
> >> language_fan wrote:
> >>> Wed, 21 Oct 2009 11:07:29 -0400, Robert Jacques thusly wrote:
> >>>> My issue was that all your example _showed_ was nominal typing. Though I didn't mention it by name, I did mention that if SOL tuples had structural typing, it might would be a different story. (Well, until/if opImplicitCast was implemented, as it would allow for structural typing.)
> >>> 
> >>> Why do you insist on using nominal typing for tuples and the library defined "literal". If I want plain old tuples without any kind of type name, why should I care about extra hand waving needed to make it work.
> >> 
> >> I'm late in this dialog, but I'm not seeing an impediment here. What does it matter to you that tuples actually have a name vs. not having a name at all?
> > 
> > Using tuples in D is a major pain in the ass. In fact it has been made so hard that people start avoiding the feature like plague. I wrote some test code to reveal how inconsistent their semantics are. Note that you need the built-in tuples for some stuff, like assigning and mixed value/ type tuples. Stuples can only be used as values and when the auto- flattening is not desired.
> > 
> >>>> STARTS HERE
> 
> Even though not being an expert in Python (have not really used it), as an experiment I managed to successfully port the examples in 2 minutes without any kind of problems.

I think this is an important point too. Maybe tuples are not *that* broken as stated in this thread, but they are quite more complex to understand than tuples in other languages, and they feel somehow hackish.

> a = (1,1)
> e1 = a[0]
> 
> print a
> 
> def retTest():
>   return (1,1)
> 
> (d,e) = (10,20)
> 
> (d,_) = (10,20)
> 
> (d,b) = (1, retTest())
> 
> a3b = [ (1,1), (2,2) ]
> 
> a7 = { (1,1) : 5 }
> 
> a8 = { 5 : (1,1)}

In python you can even do:

def f(a, b, c):
	print a, b, c

x = (b, c)
f(a, *x) # calls to f(a, b, c)

I think this is only possible in D with type tuples, not with ... "value tuples"? That's part of the complexity, having 2 type of tuples is very confusing.

-- 
Leandro Lucarella (AKA luca)                     http://llucax.com.ar/
----------------------------------------------------------------------
GPG Key: 5F5A8D05 (F8CD F9A7 BF00 5431 4145  104C 949E BFB6 5F5A 8D05)
----------------------------------------------------------------------
You are the very reason why everything happens to you
October 21, 2009
language_fan wrote:
> Wed, 21 Oct 2009 12:35:35 -0500, Andrei Alexandrescu thusly wrote:
> 
>> language_fan wrote:
>>> void main() {
>>>   Tuple!(int,int) a; // typeof(this) *is* the official tuple type
>>>   STuple!(int,int) b;  // this is actually a struct
>>>
>>>   a = Tuple!(1,1);  // ok
>> That doesn't work for me at all (with std.typecons.Tuple). I think there
>> is confusion about a couple of things. One is that Tuple!(int, int) is a
>> type that contains two ints, whereas Tuple!(1, 1) is a type that
>> contains two compile-time integral values. So if you write:
>>
>> a = Tuple!(1, 1);
>>
>> that is as good syntactically as:
>>
>> a = int;
> 
> It might be if we use your definition of tuple. But the mighty compiler dmd 2.035 himself calls my types constructed with my template
> 
>>> template Tuple(T...) { alias T Tuple; }
> 
> a tuple. How do you explain that? If the resulting type is tuple according to dmd, why do you think it is actually not.
> 
> If it works like you say, why does this work then?
> 
>>>  Tuple!(int,int) a;
>>>  a = Tuple!(12,13);
> 
> Here 'a' has a real runtime type (int,int) which is a runtime tuple according to dmd. And I assign a value to the tuple on runtime. I can even test it by printing the values a[0] and a[1] with writefln. So why didn't you just fix this particular tuple type and why did you come up with a library level hack?
> 
> Show me a better way to achieve this with your tuple system.

I don't understand what you are trying to accomplish. As far as I can tell you want to do this:

Tuple!(int, int) a;
a = tuple(12, 13);
int x = a.field[0];

and similar things. I have no idea why you refuse to do it that way.

>>>  int d,e;
>>>  Tuple!(d,e) = Tuple!(10,20);
> 
> It's still not clear to me why you don't want to add full syntactic support for built-in tuples. Do you somehow find this kind of code difficult to read or maintain?
> 
> (int,int) a = (1,1);
> int e1 = a[0];
> 
> writefln(a);
> 
> (int,int) retTest() { return (1,1); }
> 
> int d,e;
> 
> (d,e) = (10,20);
> 
> (d,_) = (10,20);
> 
> (int,int) b;
> (d,b) = (1, retTest());
> 
> auto a3b = [ (1,1), (2,2) ];
> 
> auto a7 = [ (1,1) : 5 ];
> 
> auto a8 = [ 5 : (1,1)];
> 
> I want to know what is the rationale behind not accepting this semantics that is so widely used in other languages (and I very well mean the languages that *have* built-in tuple types).

To effect this, there'd first be a need to eliminate the current semantics of the comma operator. I probably find it as useless as the next guy, and don't take one second to buy into Walter's theory that it makes it easy to generate code (that may as well be his least convincing argument to date), but really there's two parts to your suggestion: (1) eliminate the comma operator, (2) make the comma operator work for tuples. I suspect there are some syntactical issues with (2).


Andrei
October 21, 2009
Leandro Lucarella:

> In python you can even do:
> 
> def f(a, b, c):
> 	print a, b, c
> 
> x = (b, c)
> f(a, *x) # calls to f(a, b, c)

In Python2.x you can also do:

def foo(x, (y, (z1, z2))):
    print z2
    print z1
    print y
    print x

Z = (1, 2)
yz = [0, Z]
foo(-1, yz)

That outputs:

2
1
0
-1

Bye,
bearophile
October 21, 2009
Wed, 21 Oct 2009 13:41:50 -0500, Andrei Alexandrescu thusly wrote:

> I don't understand what you are trying to accomplish. As far as I can tell you want to do this:
> 
> Tuple!(int, int) a;
> a = tuple(12, 13);
> int x = a.field[0];

Not only that, but also this:

>>>>  int d,e;
>>>>  Tuple!(d,e) = Tuple!(10,20);

> and similar things. I have no idea why you refuse to do it that way.

You somehow refuse to see that D has a tuple type which the compiler calls a tuple. Run 'strings /path/to/dmd|wc -l' and you'll see 28 instances of the word 'tuple'. If there was no built-in support, why does the executable contain the word then?

Here..

>> template Z(T...) { alias T Z; }
>> Z!(int,int) a;
>> pragma(msg,a.stringof);

I did not mention the word tuple, but guess what dmd thinks. If it is not a tuple, why does dmd output 'tuple(_a_field_0,_a_field_1)'? Apparently this does not follow the math book definition of tuple nor is the traditional FPL tuple, but a special D flavor of tuple.

Walter decided to build a tuple type, but something happened and he later started restricting its use (IIRC it *was* possible to create an array of these tuples, but now it is disallowed). What is left is a half-working mess mostly useful for compile time meta-programming. It works rather nicely there (except that the auto-flattening is sometimes rather annoying), but its operation is broken on runtime. You discarded this by stating that D does not have a tuple type, you just call it a 'type that contains two ints' in my example. DMD calls it a tuple (see .stringof, error messages etc.)

I can see that you try to accomplish the same things with your library provided version of tuple. But if that is the recommended way of using tuples, why there is a bug riddled version in the compiler of the same type. It is extremely exhausting to implement a new compiler for D because the reference implementation is full of bugs I mentioned in previous posts and you cannot really tell how it should work.

> To effect this, there'd first be a need to eliminate the current semantics of the comma operator. I probably find it as useless as the next guy, and don't take one second to buy into Walter's theory that it makes it easy to generate code (that may as well be his least convincing argument to date), but really there's two parts to your suggestion: (1) eliminate the comma operator, (2) make the comma operator work for tuples. I suspect there are some syntactical issues with (2).

I know that very well..
October 21, 2009
On Wed, 21 Oct 2009 22:41:50 +0400, Andrei Alexandrescu <SeeWebsiteForEmail@erdani.org> wrote:

> language_fan wrote:
>> Wed, 21 Oct 2009 12:35:35 -0500, Andrei Alexandrescu thusly wrote:
>>
>>> language_fan wrote:
>>>> void main() {
>>>>   Tuple!(int,int) a; // typeof(this) *is* the official tuple type
>>>>   STuple!(int,int) b;  // this is actually a struct
>>>>
>>>>   a = Tuple!(1,1);  // ok
>>> That doesn't work for me at all (with std.typecons.Tuple). I think there
>>> is confusion about a couple of things. One is that Tuple!(int, int) is a
>>> type that contains two ints, whereas Tuple!(1, 1) is a type that
>>> contains two compile-time integral values. So if you write:
>>>
>>> a = Tuple!(1, 1);
>>>
>>> that is as good syntactically as:
>>>
>>> a = int;
>>  It might be if we use your definition of tuple. But the mighty compiler dmd 2.035 himself calls my types constructed with my template
>>
>>>> template Tuple(T...) { alias T Tuple; }
>>  a tuple. How do you explain that? If the resulting type is tuple according to dmd, why do you think it is actually not.
>>  If it works like you say, why does this work then?
>>
>>>>  Tuple!(int,int) a;
>>>>  a = Tuple!(12,13);
>>  Here 'a' has a real runtime type (int,int) which is a runtime tuple according to dmd. And I assign a value to the tuple on runtime. I can even test it by printing the values a[0] and a[1] with writefln. So why didn't you just fix this particular tuple type and why did you come up with a library level hack?
>>  Show me a better way to achieve this with your tuple system.
>
> I don't understand what you are trying to accomplish. As far as I can tell you want to do this:
>
> Tuple!(int, int) a;
> a = tuple(12, 13);
> int x = a.field[0];
>
> and similar things. I have no idea why you refuse to do it that way.
>
>>>>  int d,e;
>>>>  Tuple!(d,e) = Tuple!(10,20);
>>  It's still not clear to me why you don't want to add full syntactic support for built-in tuples. Do you somehow find this kind of code difficult to read or maintain?
>>  (int,int) a = (1,1);
>> int e1 = a[0];
>>  writefln(a);
>>  (int,int) retTest() { return (1,1); }
>>  int d,e;
>>  (d,e) = (10,20);
>>  (d,_) = (10,20);
>>  (int,int) b;
>> (d,b) = (1, retTest());
>>  auto a3b = [ (1,1), (2,2) ];
>>  auto a7 = [ (1,1) : 5 ];
>>  auto a8 = [ 5 : (1,1)];
>>  I want to know what is the rationale behind not accepting this semantics that is so widely used in other languages (and I very well mean the languages that *have* built-in tuple types).
>
> To effect this, there'd first be a need to eliminate the current semantics of the comma operator. I probably find it as useless as the next guy, and don't take one second to buy into Walter's theory that it makes it easy to generate code (that may as well be his least convincing argument to date), but really there's two parts to your suggestion: (1) eliminate the comma operator, (2) make the comma operator work for tuples. I suspect there are some syntactical issues with (2).
>
>
> Andrei

Well, he could just change the symbol used to denote comma operator to some other character (if he uses it so heavily internally), and don't expose it to a user.

I don't use tuples a lot myself, but I would love to have multiple return types without some clumsy syntax. It's possible even now, but the syntax is a bit discouraging:

Tuple!(int,float) foo()
{
    return tuple(42, -1.0f);
}

make_tuple(a, b) = foo();

as opposed to:

(int, float) foo()
{
    return (42, -1.0f);
}

(a, b) = foo();
October 21, 2009
Denis Koroskin wrote:
> On Wed, 21 Oct 2009 22:41:50 +0400, Andrei Alexandrescu <SeeWebsiteForEmail@erdani.org> wrote:
> 
>> language_fan wrote:
>>> Wed, 21 Oct 2009 12:35:35 -0500, Andrei Alexandrescu thusly wrote:
>>>
>>>> language_fan wrote:
>>>>> void main() {
>>>>>   Tuple!(int,int) a; // typeof(this) *is* the official tuple type
>>>>>   STuple!(int,int) b;  // this is actually a struct
>>>>>
>>>>>   a = Tuple!(1,1);  // ok
>>>> That doesn't work for me at all (with std.typecons.Tuple). I think there
>>>> is confusion about a couple of things. One is that Tuple!(int, int) is a
>>>> type that contains two ints, whereas Tuple!(1, 1) is a type that
>>>> contains two compile-time integral values. So if you write:
>>>>
>>>> a = Tuple!(1, 1);
>>>>
>>>> that is as good syntactically as:
>>>>
>>>> a = int;
>>>  It might be if we use your definition of tuple. But the mighty compiler dmd 2.035 himself calls my types constructed with my template
>>>
>>>>> template Tuple(T...) { alias T Tuple; }
>>>  a tuple. How do you explain that? If the resulting type is tuple according to dmd, why do you think it is actually not.
>>>  If it works like you say, why does this work then?
>>>
>>>>>  Tuple!(int,int) a;
>>>>>  a = Tuple!(12,13);
>>>  Here 'a' has a real runtime type (int,int) which is a runtime tuple according to dmd. And I assign a value to the tuple on runtime. I can even test it by printing the values a[0] and a[1] with writefln. So why didn't you just fix this particular tuple type and why did you come up with a library level hack?
>>>  Show me a better way to achieve this with your tuple system.
>>
>> I don't understand what you are trying to accomplish. As far as I can tell you want to do this:
>>
>> Tuple!(int, int) a;
>> a = tuple(12, 13);
>> int x = a.field[0];
>>
>> and similar things. I have no idea why you refuse to do it that way.
>>
>>>>>  int d,e;
>>>>>  Tuple!(d,e) = Tuple!(10,20);
>>>  It's still not clear to me why you don't want to add full syntactic support for built-in tuples. Do you somehow find this kind of code difficult to read or maintain?
>>>  (int,int) a = (1,1);
>>> int e1 = a[0];
>>>  writefln(a);
>>>  (int,int) retTest() { return (1,1); }
>>>  int d,e;
>>>  (d,e) = (10,20);
>>>  (d,_) = (10,20);
>>>  (int,int) b;
>>> (d,b) = (1, retTest());
>>>  auto a3b = [ (1,1), (2,2) ];
>>>  auto a7 = [ (1,1) : 5 ];
>>>  auto a8 = [ 5 : (1,1)];
>>>  I want to know what is the rationale behind not accepting this semantics that is so widely used in other languages (and I very well mean the languages that *have* built-in tuple types).
>>
>> To effect this, there'd first be a need to eliminate the current semantics of the comma operator. I probably find it as useless as the next guy, and don't take one second to buy into Walter's theory that it makes it easy to generate code (that may as well be his least convincing argument to date), but really there's two parts to your suggestion: (1) eliminate the comma operator, (2) make the comma operator work for tuples. I suspect there are some syntactical issues with (2).
>>
>>
>> Andrei
> 
> Well, he could just change the symbol used to denote comma operator to some other character (if he uses it so heavily internally), and don't expose it to a user.
> 
> I don't use tuples a lot myself, but I would love to have multiple return types without some clumsy syntax. It's possible even now, but the syntax is a bit discouraging:
> 
> Tuple!(int,float) foo()
> {
>     return tuple(42, -1.0f);
> }
> 
> make_tuple(a, b) = foo();
> 
> as opposed to:
> 
> (int, float) foo()
> {
>     return (42, -1.0f);
> }
> 
> (a, b) = foo();

Or even:

a, b = foo();

or

a, _ = foo();

Works in Python (tm)
October 21, 2009
grauzone, el 21 de octubre a las 22:12 me escribiste:
> Or even:
> 
> a, b = foo();
> 
> or
> 
> a, _ = foo();
> 
> Works in Python (tm)

_ is a regular symbol (variable name in this case), there is nothing special about the second form, which is exactly the same as the first. And BTW, the trailing ; is not needed ;)

-- 
Leandro Lucarella (AKA luca)                     http://llucax.com.ar/
----------------------------------------------------------------------
GPG Key: 5F5A8D05 (F8CD F9A7 BF00 5431 4145  104C 949E BFB6 5F5A 8D05)
----------------------------------------------------------------------
Hey you, standing in the aisles
With itchy feet and fading smiles
Can you feel me?
October 21, 2009
language_fan wrote:
> You somehow refuse to see that D has a tuple type which the compiler calls a tuple.

D has tuples, it doesn't have tuple literals. Tuple attempts to supplant that.


Andrei