View mode: basic / threaded / horizontal-split · Log in · Help
October 21, 2009
Re: static arrays becoming value types
Tue, 20 Oct 2009 16:25:05 -0400, Robert Jacques thusly wrote:

> On Tue, 20 Oct 2009 15:19:15 -0400, language_fan <foo@bar.com.invalid>
> wrote:
> 
>> Real tuple types do not have a special type tag which gets injected
>> implicitly with structs. So every time you try to do something
>> lightweight by emulating tuples, you need to refer to the global Tuple
>> type or bang your head to the wall.
> 
> Or use a templated opAssign mixin to allow two desperate types to be
> assigned to each other.

Wow, you need templates to implement == for built-in values types, nice..

> Besides, I think you're comparing apples to oranges. In the SOL example,
> you use the same declaration for all types. Shouldn't the SOL example
> be:
> 
>    val a = (1,2) : [Int,Int]
>    val b = (1,2) : [Int,Int]
>    val c = (2,3) : MyCustomTupleType[Int,Int]
> 
> which would probably generate:
>       assert(a == b); // ok
>       assert(a != c); // Error: incompatible types for ((a) != (b))

If you have built-in tuple literals, there is no way you can build a 
MyCustomTupleType without resorting to other language features. There are 
no apples and oranges, cause they both are seen as (Int,Int) by the 
equivalence checker. Do you understand how equivalence works in 
structural typing system (http://en.wikipedia.org/wiki/
Structural_type_system) vs nominal typing? In structural equivalence 
there are no names attached to the types (well there might be, but those 
are omitted in the comparison), only their internal structure matters.

Why would anyone want to create two incompatible tuples by default as you 
still would have 'typedef' and 'struct' for implementing just that.
October 21, 2009
Re: static arrays becoming value types
Yigal Chripun, el 21 de octubre a las 07:18 me escribiste:
> On 21/10/2009 05:48, Robert Jacques wrote:
> >On Tue, 20 Oct 2009 23:30:48 -0400, Leandro Lucarella <llucax@gmail.com>
> >wrote:
> >>Robert Jacques, el 20 de octubre a las 21:06 me escribiste:
> >>>Now, if SOL allowed tuples to do things you can't do today in D,
> >>>like assign a tuple to a struct with the same signature, then this
> >>>might be a point. But that wasn't the example given.
> >>
> >>Yes, that's another thing that can be done without real tuple support in
> >>the language. Anyway, I guess I was a little exaggerated with '*way far*
> >>from ideal', but I'm convinced there is plenty of room for improvements.
> >>=)
> >>
> >
> >Would you happen to know of a language which does tuples well already?
> 
> pick any functional language.. my favorite is ML

Or Python ;)

-- 
Leandro Lucarella (AKA luca)                     http://llucax.com.ar/
----------------------------------------------------------------------
GPG Key: 5F5A8D05 (F8CD F9A7 BF00 5431 4145  104C 949E BFB6 5F5A 8D05)
----------------------------------------------------------------------
HACIA NEUQUEN: EL JUEVES SALDRA CARAVANA CON PERROS
DESDE CAPITAL EN APOYO AL CACHORRO CONDENADO A MUERTE
	-- Crónica TV
October 21, 2009
Re: static arrays becoming value types
On Wed, 21 Oct 2009 02:23:09 -0400, language_fan <foo@bar.com.invalid>  
wrote:
> Tue, 20 Oct 2009 16:25:05 -0400, Robert Jacques thusly wrote:
>
>> On Tue, 20 Oct 2009 15:19:15 -0400, language_fan <foo@bar.com.invalid>
>> wrote:
>>
>>> Real tuple types do not have a special type tag which gets injected
>>> implicitly with structs. So every time you try to do something
>>> lightweight by emulating tuples, you need to refer to the global Tuple
>>> type or bang your head to the wall.
>>
>> Or use a templated opAssign mixin to allow two desperate types to be
>> assigned to each other.
>
> Wow, you need templates to implement == for built-in values types, nice..

Unlike C++, D templates don't require a PhD to use. And it's definitely  
better that banging your head against the wall.

>> Besides, I think you're comparing apples to oranges. In the SOL example,
>> you use the same declaration for all types. Shouldn't the SOL example
>> be:
>>
>>    val a = (1,2) : [Int,Int]
>>    val b = (1,2) : [Int,Int]
>>    val c = (2,3) : MyCustomTupleType[Int,Int]
>>
>> which would probably generate:
>>       assert(a == b); // ok
>>       assert(a != c); // Error: incompatible types for ((a) != (b))
>
> If you have built-in tuple literals, there is no way you can build a
> MyCustomTupleType without resorting to other language features. There are
> no apples and oranges, cause they both are seen as (Int,Int) by the
> equivalence checker. Do you understand how equivalence works in
> structural typing system (http://en.wikipedia.org/wiki/
> Structural_type_system) vs nominal typing? In structural equivalence
> there are no names attached to the types (well there might be, but those
> are omitted in the comparison), only their internal structure matters.
>
> Why would anyone want to create two incompatible tuples by default as you
> still would have 'typedef' and 'struct' for implementing just that.

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.)
October 21, 2009
Re: static arrays becoming value types
Wed, 21 Oct 2009 11:07:29 -0400, Robert Jacques thusly wrote:

> On Wed, 21 Oct 2009 02:23:09 -0400, language_fan <foo@bar.com.invalid>
> wrote:
>> Tue, 20 Oct 2009 16:25:05 -0400, Robert Jacques thusly wrote:
>>
>>> On Tue, 20 Oct 2009 15:19:15 -0400, language_fan <foo@bar.com.invalid>
>>> wrote:
>>>
>>>> Real tuple types do not have a special type tag which gets injected
>>>> implicitly with structs. So every time you try to do something
>>>> lightweight by emulating tuples, you need to refer to the global
>>>> Tuple type or bang your head to the wall.
>>>
>>> Or use a templated opAssign mixin to allow two desperate types to be
>>> assigned to each other.
>>
>> Wow, you need templates to implement == for built-in values types,
>> nice..
> 
> Unlike C++, D templates don't require a PhD to use. And it's definitely
> better that banging your head against the wall.
> 
>>> Besides, I think you're comparing apples to oranges. In the SOL
>>> example, you use the same declaration for all types. Shouldn't the SOL
>>> example be:
>>>
>>>    val a = (1,2) : [Int,Int]
>>>    val b = (1,2) : [Int,Int]
>>>    val c = (2,3) : MyCustomTupleType[Int,Int]
>>>
>>> which would probably generate:
>>>       assert(a == b); // ok
>>>       assert(a != c); // Error: incompatible types for ((a) != (b))
>>
>> If you have built-in tuple literals, there is no way you can build a
>> MyCustomTupleType without resorting to other language features. There
>> are no apples and oranges, cause they both are seen as (Int,Int) by the
>> equivalence checker. Do you understand how equivalence works in
>> structural typing system (http://en.wikipedia.org/wiki/
>> Structural_type_system) vs nominal typing? In structural equivalence
>> there are no names attached to the types (well there might be, but
>> those are omitted in the comparison), only their internal structure
>> matters.
>>
>> Why would anyone want to create two incompatible tuples by default as
>> you still would have 'typedef' and 'struct' for implementing just that.
> 
> 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 
see opImplicitCast, introspection done with templates and all kinds of 
other voodoo to be ugly hacks. This is nothing more than one of the basic 
value types without any special semantics, for $deity's sake. If you like 
the hacky approach so much, why don't all built-in types (like static 
arrays etc.) use the same method? Implementation wise tuples are much 
simpler than D's arrays or AAs, still they are treated like some 2nd 
class citizen from some notorious 3rd world country.

Why is it so damn hard to change the 90% correctly implemented built-in 
tuples to work like in any other tuple supporting language. Do you 
somehow fancy verbose syntax for C++ compatibility reasons (ah, the good 
old std::tr1::make_tuple<int, int>, makes me want to wank every time..) 
Try Ruby, try python, try *ML etc. They all somehow got it right.
October 21, 2009
Re: static arrays becoming value types
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?

> I 
> see opImplicitCast, introspection done with templates and all kinds of 
> other voodoo to be ugly hacks. This is nothing more than one of the basic 
> value types without any special semantics, for $deity's sake. If you like 
> the hacky approach so much, why don't all built-in types (like static 
> arrays etc.) use the same method? Implementation wise tuples are much 
> simpler than D's arrays or AAs, still they are treated like some 2nd 
> class citizen from some notorious 3rd world country.

How and why are they treated badly?

> Why is it so damn hard to change the 90% correctly implemented built-in 
> tuples to work like in any other tuple supporting language. Do you 
> somehow fancy verbose syntax for C++ compatibility reasons (ah, the good 
> old std::tr1::make_tuple<int, int>, makes me want to wank every time..) 
> Try Ruby, try python, try *ML etc. They all somehow got it right.

What exactly didn't D's tuples get right?


Andrei
October 21, 2009
Re: static arrays becoming value types
On Wed, Oct 21, 2009 at 8:48 AM, Andrei Alexandrescu
<SeeWebsiteForEmail@erdani.org> 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?
>
>> I see opImplicitCast, introspection done with templates and all kinds of
>> other voodoo to be ugly hacks. This is nothing more than one of the basic
>> value types without any special semantics, for $deity's sake. If you like
>> the hacky approach so much, why don't all built-in types (like static arrays
>> etc.) use the same method? Implementation wise tuples are much simpler than
>> D's arrays or AAs, still they are treated like some 2nd class citizen from
>> some notorious 3rd world country.
>
> How and why are they treated badly?
>
>> Why is it so damn hard to change the 90% correctly implemented built-in
>> tuples to work like in any other tuple supporting language. Do you somehow
>> fancy verbose syntax for C++ compatibility reasons (ah, the good old
>> std::tr1::make_tuple<int, int>, makes me want to wank every time..) Try
>> Ruby, try python, try *ML etc. They all somehow got it right.
>
> What exactly didn't D's tuples get right?

Well, auto-flattening is a colossally bad idea to be sure.

--bb
October 21, 2009
Re: static arrays becoming value types
Bill Baxter wrote:
> Well, auto-flattening is a colossally bad idea to be sure.

Well that I agree with. I wonder if we need to fix it for D2. If we 
don't, we risk to live with it like with a chronic cough.

Andrei
October 21, 2009
Re: static arrays becoming value types
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

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

struct STuple(T...) {
 T t;
}

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
 // Tuple!(int,int) a2 = Tuple!(1,1); // WTF? Error: cannot implicitly 
convert expression (tuple(1,1)) of type (int, int) to int
 auto a3 = Tuple!(1,1); // ok


 b = STuple!(int,int)(1,1); // no easier way? make_tuple!(1,1) ?
 STuple!(int,int) b2 = STuple!(int,int)(1,1); // ok, but very verbose


 auto e1 = a[0];  // ok

 //auto e2 = b[0]; // nope
 auto e3 = b.t[0]; // this is how it works - you could possibly define 
opIndex but how would it work with different types then

  writefln("%s", a); // we get.. 1 !? but..
  writefln("%s", typeof(a).stringof); // (int, int)
  writefln("%s", b); // STuple!(int,int)(1, 1) - rather verbose, but 
suffices


 //auto retTest() { return STuple!(int,int)(1,1); } // no identifier for 
declarator retTest

 STuple!(int,int) retTest2() { return STuple!(int,int)(1,1); }; // ok, 
but a bit too verbose

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

 // but how to discard an unnecessary value? e.g. (a, _) = (1, 2)

 // Tuple!(d,e) = STuple!(10,20); // nope, not interchangeable
 // b = STuple!(a); // same here

 a = a; // ok
 b = b; // ok
 // a = b; // Error: a is not an lvalue -- interesting!


 Tuple!(d,b) = Tuple!(1, retTest2()); // awesome, with the Tuple I can 
even assign Tuples of STuples!
 //Tuple!(d,a) = Tuple!(1, a); // but Tuples don't help when assigning 
Tuples of Tuples

   //test.d(12): Error: expression _a_field_0 is not a valid template 
value argument
   //test.d(12): Error: expression _a_field_1 is not a valid template 
value argument
   //test.d(47): Error: template instance test.Tuple!
(1,_a_field_0,_a_field_1) error instantiating

 // LET'S MAKE ARRAYS!

  int[] a1; // ok
  int[][] a2; // ok
  auto a1b = [1,2,3]; // ok
  auto a2b = [[1],[2],[3]]; // ok

  //Tuple!(int,int)[] a4; // Error: can't have array of (int, int) -- 
WHY NOT - it's simple, try e.g. ML
  STuple!(int,int)[] a5; // ok

  auto a3b = [Tuple!(1,1)]; // works, but hey did you know this is an 
array of ints!

  auto a4b = [STuple!(int,int)(1,1)]; // ok

  // int[Tuple!(int,int)] a6; // Error: can't have associative array key 
of (int, int)
  int[STuple!(int,int)] a7; // ok

  a7[STuple!(int,int)(1,1)] = 5; // ok

  Tuple!(int,Tuple!(int,int)) a8; // this isn't a (int, (int,int)) tuple 
- it's (int,int,int) !
  STuple!(int,STuple!(int,int)) a9; // ok

  //auto a10 = [ Tuple!(1,1) : 2 ]; // Error: can't have associative 
array key of (int, int) -- Why did this work in array literal then?!

  auto a11 = [ STuple!(int,int)(1,1) : 2 ]; // ok

  alias Tuple!(int, 5) foo;
  // alias STuple!(int, 5) foo2; // parameters can only be types
}
October 21, 2009
Re: static arrays becoming value types
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.

I forgot to say that you need two kinds of tuple "literals" in your 
standard library in D: one with value semantics, and one that is a 
wrapper around the alias tuple since auto-flattening happens.
October 21, 2009
Re: static arrays becoming value types
language_fan 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.

How do you know what "people" do?

> 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
> 
> template Tuple(T...) { alias T Tuple; }

Why do you define Tuple instead of using the standard std.typecons.tuple?

> struct STuple(T...) {
>   T t;
> }

Why do you insist on defining another tuple type instead of using the 
one provided by the standard library?

> 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;

which I hope you agree shouldn't quite go through. Write this:

Tuple!(int,int) a;
a = tuple(1, 1);

or this:

auto a = tuple(1, 1);

>   // Tuple!(int,int) a2 = Tuple!(1,1); // WTF? Error: cannot implicitly 
> convert expression (tuple(1,1)) of type (int, int) to int

Yeah, WTF that doesn't work either:

int a2 = int;

>   auto a3 = Tuple!(1,1); // ok

Not ok on my machine, nor it should be ok as this is also not ok:

auto a3 = int;

>   b = STuple!(int,int)(1,1); // no easier way? make_tuple!(1,1) ?

Yeah try tuple(1, 1) in conjunction with std.typecons.Tuple.

>   STuple!(int,int) b2 = STuple!(int,int)(1,1); // ok, but very verbose

Well write this:

auto stuple(T...)(T args) {
    return STuple!(T)(args);
}

>   auto e1 = a[0];  // ok

This doesn't work because of a bug in the compiler, but this does with 
std.typecons.Tuple:

auto e1 = a.field[0];

etc. etc. etc.

I'm sure you make a couple of good points, but they are difficult to 
find. I suggest you peruse std.typecons.Tuple and submit any bugs you 
find to bugzilla.


Andrei
1 2 3 4 5 6
Top | Discussion index | About this forum | D home