www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Const Tuples

reply "bearophile" <bearophileHUGS lycos.com> writes:
They are not the same type:


void main() {
     import std.typecons: Tuple;
     alias T1 = const Tuple!(int, int);
     alias T2 = Tuple!(const int, const int);
     static assert(is(T1 == T2)); // Fails.
}


This type difference causes some troubles when you use tuples.

Bye,
bearophile
Apr 25 2014
next sibling parent reply "Dicebot" <public dicebot.lv> writes:
On Friday, 25 April 2014 at 11:51:48 UTC, bearophile wrote:
 They are not the same type:


 void main() {
     import std.typecons: Tuple;
     alias T1 = const Tuple!(int, int);
     alias T2 = Tuple!(const int, const int);
     static assert(is(T1 == T2)); // Fails.
 }


 This type difference causes some troubles when you use tuples.

 Bye,
 bearophile
Why would you even expect those to be same types? These 2 types are also different: struct A { const int x; } alias A_ = const(A);
Apr 25 2014
parent reply "bearophile" <bearophileHUGS lycos.com> writes:
Dicebot:

 Why would you even expect those to be same types? These 2 types 
 are also different:

 struct A
 {
     const int x;
 }

 alias A_ = const(A);
In general a tuple is a higher level data structure compared to a struct. So it's not unreasonable to expect a Tuple to be more flexible than a struct. But in the specific const tuple case I don't know if it's a good idea to ask for a const tuple to be of the same type of a tuple with all const fields. I was just expressing a little frustration :-) Bye, bearophile
Apr 25 2014
next sibling parent reply "Dicebot" <public dicebot.lv> writes:
On Friday, 25 April 2014 at 12:17:31 UTC, bearophile wrote:
 In general a tuple is a higher level data structure compared to 
 a struct. So it's not unreasonable to expect a Tuple to be more 
 flexible than a struct.
Well, wrong :) std.typecons.Tuple IS a struct - https://github.com/D-Programming-Language/phobos/blob/master/std/typecons.d#L388
 But in the specific const tuple case I don't know if it's a 
 good idea to ask for a const tuple to be of the same type of a 
 tuple with all const fields.
It would be weird exception of general type system rules with no practical justification I can readily imagine.
 I was just expressing a little frustration :-)

 Bye,
 bearophile
Apr 25 2014
next sibling parent reply "bearophile" <bearophileHUGS lycos.com> writes:
Dicebot:

 Well, wrong :) std.typecons.Tuple IS a struct - 
 https://github.com/D-Programming-Language/phobos/blob/master/std/typecons.d#L388
Nope, that's just an implementation detail. They are two quite different data structures. Example: slicing a tuple always has a meaning, while slicing a struct is in general meaningless. Bye, bearophile
Apr 25 2014
parent reply "Dicebot" <public dicebot.lv> writes:
On Friday, 25 April 2014 at 12:42:33 UTC, bearophile wrote:
 Dicebot:

 Well, wrong :) std.typecons.Tuple IS a struct - 
 https://github.com/D-Programming-Language/phobos/blob/master/std/typecons.d#L388
Nope, that's just an implementation detail. They are two quite different data structures. Example: slicing a tuple always has a meaning, while slicing a struct is in general meaningless. Bye, bearophile
It was what you want it to be, not what it is :) Slicing a struct is absolutely routine thing as struct is just a user-defined aggregate type. std.typecons.Tuple is just a subset of all structs implementing specific behavior. It still acts as struct everywhere when applicable. Don't confuse std.typecons.Tuple and built-in template argument lists. Latter are indeed special type system entities. Former is just a smart struct.
Apr 25 2014
parent reply "bearophile" <bearophileHUGS lycos.com> writes:
Dicebot:

 std.typecons.Tuple is just a subset of all structs implementing 
 specific behavior. It still acts as struct everywhere when 
 applicable.
A subset is not the same as the whole set. You are missing something important about what a data structure is. Take a look at your computer science books. Another example: a dynamic array allows several operations, including append at the end and pop from the end. If I define a Stack data structure based on a dynamic array with just its pop/append/empty/length operations, I have defined a new data structure. Bye, bearophile
Apr 25 2014
parent "Dicebot" <public dicebot.lv> writes:
On Friday, 25 April 2014 at 12:54:25 UTC, bearophile wrote:
 Dicebot:

 std.typecons.Tuple is just a subset of all structs 
 implementing specific behavior. It still acts as struct 
 everywhere when applicable.
A subset is not the same as the whole set. You are missing something important about what a data structure is. Take a look at your computer science books. Another example: a dynamic array allows several operations, including append at the end and pop from the end. If I define a Stack data structure based on a dynamic array with just its pop/append/empty/length operations, I have defined a new data structure. Bye, bearophile
I am not interested in academic definitions. D is not an academic language (thanks gods!) and expecting it to prioritize formal concepts over mundane pragmatism only leads to frustration. The fact that you can use D rules to emulate certain concept as a user-defined type does not make domain semantics of that type more important than language. It is still a second-class citizen. You don't change language rules by creating new data structures. Type system still must prevail :)
Apr 25 2014
prev sibling parent reply "bearophile" <bearophileHUGS lycos.com> writes:
Dicebot:

 It would be weird exception of general type system rules with 
 no practical justification I can readily imagine.
I partially disagree. It could be useful to have structural typing (http://en.wikipedia.org/wiki/Structural_type_system ) only on tuples (and not on structs), because the formal definition of tuple goes well with structural typing. This also implies the type equivalence of const tuple with a tuple of const fields. Bye, bearophile
Apr 25 2014
parent reply "Dicebot" <public dicebot.lv> writes:
On Friday, 25 April 2014 at 13:18:13 UTC, bearophile wrote:
 Dicebot:

 It would be weird exception of general type system rules with 
 no practical justification I can readily imagine.
I partially disagree. It could be useful to have structural typing (http://en.wikipedia.org/wiki/Structural_type_system ) only on tuples (and not on structs), because the formal definition of tuple goes well with structural typing. This also implies the type equivalence of const tuple with a tuple of const fields. Bye, bearophile
Again, you refer to some sort of formal definition of tuple which is not applicable to D. We don't have real tuples in D. There are structures that emulate some of tuple properties and there is a built-in feature that is called tuple but is not one in practice. For your objections to make sense tuple would need to be inroduced as completely new first class type system entity. As this will never happen, discussion of imaginary "proper" tuple traits is also unapplicable.
Apr 25 2014
parent "bearophile" <bearophileHUGS lycos.com> writes:
Dicebot:

 For your objections to make sense tuple would need to be 
 inroduced as completely new first class type system entity. As 
 this will never happen,
I think first class tuples will happen in D, because the current tuple situation is quite bad. But this thread is not about built-in tuples, here we are discussing about possible improvements to the Phobos implementation of tuples. A possible solution is an optional " structural" attribute for structs that gives structural typing to one struct (that will be used as underlying implementation for library-defined tuples. Bye, bearophile
Apr 25 2014
prev sibling parent reply "bearophile" <bearophileHUGS lycos.com> writes:
 I was just expressing a little frustration :-)
An example; despite it looks simple I am missing something: import std.typecons: Tuple, tuple; import std.algorithm: reduce; struct Foo { int x; } auto foo(in Tuple!(Foo[]) arg, int) { return tuple(arg[0]); } void main() { int[] data; Foo[] empty; auto seed = tuple(empty); reduce!foo(seed, data); } Bye, bearophile
Apr 25 2014
parent "bearophile" <bearophileHUGS lycos.com> writes:
 import std.typecons: Tuple, tuple;
 import std.algorithm: reduce;

 struct Foo { int x; }

 auto foo(in Tuple!(Foo[]) arg, int) {
     return tuple(arg[0]);
 }

 void main() {
     int[] data;
     Foo[] empty;
     auto seed = tuple(empty);
     reduce!foo(seed, data);
 }
I have found a solution: import std.typecons: Tuple, tuple; import std.algorithm: reduce; auto foo(in Tuple!(const(int)[]) arg, int) { return tuple(arg[0]); } void main() { int[] empty; Tuple!(const(int)[]) seed; reduce!foo(seed, [1]); } Bye, bearophile
Apr 25 2014
prev sibling parent reply "Meta" <jared771 gmail.com> writes:
On Friday, 25 April 2014 at 11:51:48 UTC, bearophile wrote:
 They are not the same type:


 void main() {
     import std.typecons: Tuple;
     alias T1 = const Tuple!(int, int);
     alias T2 = Tuple!(const int, const int);
     static assert(is(T1 == T2)); // Fails.
 }


 This type difference causes some troubles when you use tuples.

 Bye,
 bearophile
I think it's a bad idea to make these equal for this reason: if T1 == T2, then you would expect Unqual!T1 == Unqual!T2. However: alias T1 = const Tuple!(int, int); alias T2 = Tuple!(const int, const int); assert(is(T1 == T2)); alias UnT1 = Unqual!T1; // Tuple!(int, int) alias UnT2 = Unqual!T2; // Tuple!(const int, const int) assert(is(UnT1 == UnT2));
Apr 25 2014
parent "bearophile" <bearophileHUGS lycos.com> writes:
Meta:

 I think it's a bad idea to make these equal for this reason: if 
 T1 == T2, then you would expect Unqual!T1 == Unqual!T2. However:

 alias T1 = const Tuple!(int, int);
 alias T2 = Tuple!(const int, const int);
 assert(is(T1 == T2));

 alias UnT1 = Unqual!T1; // Tuple!(int, int)
 alias UnT2 = Unqual!T2; // Tuple!(const int, const int)
 assert(is(UnT1 == UnT2));
If we introduce structural typing for tuples (to make T1 and T2 the same type), then Unqual!T2 is Tuple!(int, int). It's like for a const(const(int)[2]). Bye, bearophile
Apr 25 2014