static arrays becoming value types

language_fan foo at bar.com.invalid
Wed Oct 21 09:54:22 PDT 2009


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
}



More information about the Digitalmars-d mailing list