digitalmars.D - Tuples?

• Kramer (4/4) Feb 08 2006 Is there any way to simulate tuples in D currently? (hopefully that doe...
• Sean Kelly (82/84) Feb 09 2006 Yes. I just threw this example together so it could do with a bit of
• Oskar Linde (72/89) Feb 09 2006 I also threw together a quick Tuple. Actually two different implementati...
• Kramer (5/99) Feb 09 2006 Thanks for both replies. I would love it if somehow this could be incor...
• Sean Kelly (7/11) Feb 09 2006 Not really. 'auto' is great for this sort of thing:
• Sean Kelly (7/15) Feb 09 2006 It turns out that I was still thinking with a C++ mindset. No methods
```Is there any way to simulate tuples in D currently?  (hopefully that doesn't
look too hackish <g>)

-Kramer
```
Feb 08 2006
Sean Kelly <sean f4.ca> writes:
```Kramer wrote:
Is there any way to simulate tuples in D currently?  (hopefully that doesn't
look too hackish <g>)

Yes.  I just threw this example together so it could do with a bit of
cleaning up, but it works.  My only major complaint is that template
functions can't be overloaded, thus the 'get' and 'set' methods.  Also,
if you specify an out of range index, the current behavior will just do
nothing or return an instance of Empty--a better approach might be to
have a "static assert(false)" in there:

import std.c.stdio;

void main()
{
MakeTuple!(int, long) t;

printf( "%i\n", t.length );
printf( "%i\n", t.get!(0) );
printf( "%lli\n", t.get!(1) );
t.set!(0) = 1;
printf( "%i\n", t.get!(0) );
}

struct Empty
{

}

template Tuple( HeadType, TailType = Empty )
{
struct Tuple
{

TailType       tail;

int length()
{
return Length!( Tuple );
}

template get( int n )
{
TypeAt!(n,Tuple) get()
{
static if( n == 0 )
return m_val;
else static if( is( typeof( tail ) == Empty ) )
return tail;
else
return tail.get!( n - 1 );
}
}

template set( int n )
{
void set( TypeAt!(n,Tuple) newval )
{
static if( n == 0 )
m_val = newval;
else static if( is( typeof( tail ) == Empty ) )
; // do nothing
else
return tail.set!( n - 1 )( newval );
}
}

private:
}
}

template Length( T )
{
static if( is( T == Empty ) )
const int Length = 0;
else
const int Length = 1 + .Length!( typeof( T.tail ) );
}

template TypeAt( int pos, T )
{
static if( is( T == Empty ) )
alias Empty TypeAt;
else static if( pos == 0 )
alias T.Type TypeAt;
else
alias .TypeAt!( pos - 1, typeof( T.tail ) ) TypeAt;
}

template MakeTuple( T1 )
{
alias Tuple!( T1 ) MakeTuple;
}

template MakeTuple( T1, T2 )
{
alias Tuple!( T1, Tuple!( T2 ) ) MakeTuple;
}
```
Feb 09 2006
Oskar Linde <oskar.lindeREM OVEgmail.com> writes:
```In article <dsf3q0\$1497\$1 digitaldaemon.com>, Sean Kelly says...
Kramer wrote:
Is there any way to simulate tuples in D currently?  (hopefully that doesn't
look too hackish <g>)

Yes.  I just threw this example together so it could do with a bit of
cleaning up, but it works.  My only major complaint is that template
functions can't be overloaded, thus the 'get' and 'set' methods. Also,
if you specify an out of range index, the current behavior will just do
nothing or return an instance of Empty--a better approach might be to
have a "static assert(false)" in there:

[snip]
template MakeTuple( T1 )
{
alias Tuple!( T1 ) MakeTuple;
}

template MakeTuple( T1, T2 )
{
alias Tuple!( T1, Tuple!( T2 ) ) MakeTuple;
}

I also threw together a quick Tuple. Actually two different implementations.
Interestingly, one was almost identical to the above. Even most of the type and
identifier names were the same. :) MakeTuple is just a bit more briefly
implemented:

# template MakeTuple(T1=Empty, T2=Empty, T3=Empty, T4=Empty,
#                    T5=Empty, T6=Empty, T7=Empty, T8=Empty) {
#   static if (is(T1 == Empty))
#     alias Empty MakeTuple;
#   else
#     alias Tuple!(T1,MakeTuple!(T2,T3,T4,T5,T6,T7,T8)) MakeTuple;
# }

(This is just an attempt at a general implementation of ... for template
arguments)

The other version is not as elegant and more limited, but maybe a bit more
straightforward:

#import std.stdio;
#
#typedef void nulltype;
#
#struct Tuple(T1=nulltype, T2=nulltype, T3=nulltype, T4=nulltype) {
#  static if (!is(T1 == nulltype))
#    T1 v1;
#  static if (!is(T2 == nulltype))
#    T2 v2;
#  static if (!is(T3 == nulltype))
#    T3 v3;
#  static if (!is(T4 == nulltype))
#    T4 v4;
#  static if (!is(T1 == nulltype)) {
#    void assignTo(out T1 o1) {
#      o1 = v1;
#    }
#    static if (!is(T2 == nulltype)) {
#      void assignTo(out T1 o1, out T2 o2) {
#        o1 = v1; o2 = v2;
#      }
#      static if (!is(T3 == nulltype)) {
#        void assignTo(out T1 o1, out T2 o2, out T3 o3) {
#          o1 = v1; o2 = v2; o3 = v3;
#        }
#        static if (!is(T4 == nulltype)) {
#          void assignTo(out T1 o1, out T2 o2, out T3 o3, out T4 o4) {
#            o1 = v1; o2 = v2; o4 = v4;
#          }
#        }
#      }
#    }
#  }
#}
#
#
#Tuple!(int,float) func() {
#  Tuple!(int,float) ret;
#  ret.v1 = 3;
#  ret.v2 = 3.5;
#  return ret;
#}
#
#int main() {
#  Tuple!(int,float) x = func();
#  writefln("%s %s",x.v1,x.v2);
#
#  int i;
#  float f;
#  func().assignTo(i,f);
#  writefln("%s %s",i,f);
#
#  return 0;
#}

/Oskar
```
Feb 09 2006
```In article <dsf66t\$19jb\$1 digitaldaemon.com>, Oskar Linde says...
In article <dsf3q0\$1497\$1 digitaldaemon.com>, Sean Kelly says...
Kramer wrote:
Is there any way to simulate tuples in D currently?  (hopefully that doesn't
look too hackish <g>)

Yes.  I just threw this example together so it could do with a bit of
cleaning up, but it works.  My only major complaint is that template
functions can't be overloaded, thus the 'get' and 'set' methods. Also,
if you specify an out of range index, the current behavior will just do
nothing or return an instance of Empty--a better approach might be to
have a "static assert(false)" in there:

[snip]
template MakeTuple( T1 )
{
alias Tuple!( T1 ) MakeTuple;
}

template MakeTuple( T1, T2 )
{
alias Tuple!( T1, Tuple!( T2 ) ) MakeTuple;
}

I also threw together a quick Tuple. Actually two different implementations.
Interestingly, one was almost identical to the above. Even most of the type and
identifier names were the same. :) MakeTuple is just a bit more briefly
implemented:

# template MakeTuple(T1=Empty, T2=Empty, T3=Empty, T4=Empty,
#                    T5=Empty, T6=Empty, T7=Empty, T8=Empty) {
#   static if (is(T1 == Empty))
#     alias Empty MakeTuple;
#   else
#     alias Tuple!(T1,MakeTuple!(T2,T3,T4,T5,T6,T7,T8)) MakeTuple;
# }

(This is just an attempt at a general implementation of ... for template
arguments)

The other version is not as elegant and more limited, but maybe a bit more
straightforward:

#import std.stdio;
#
#typedef void nulltype;
#
#struct Tuple(T1=nulltype, T2=nulltype, T3=nulltype, T4=nulltype) {
#  static if (!is(T1 == nulltype))
#    T1 v1;
#  static if (!is(T2 == nulltype))
#    T2 v2;
#  static if (!is(T3 == nulltype))
#    T3 v3;
#  static if (!is(T4 == nulltype))
#    T4 v4;
#  static if (!is(T1 == nulltype)) {
#    void assignTo(out T1 o1) {
#      o1 = v1;
#    }
#    static if (!is(T2 == nulltype)) {
#      void assignTo(out T1 o1, out T2 o2) {
#        o1 = v1; o2 = v2;
#      }
#      static if (!is(T3 == nulltype)) {
#        void assignTo(out T1 o1, out T2 o2, out T3 o3) {
#          o1 = v1; o2 = v2; o3 = v3;
#        }
#        static if (!is(T4 == nulltype)) {
#          void assignTo(out T1 o1, out T2 o2, out T3 o3, out T4 o4) {
#            o1 = v1; o2 = v2; o4 = v4;
#          }
#        }
#      }
#    }
#  }
#}
#
#
#Tuple!(int,float) func() {
#  Tuple!(int,float) ret;
#  ret.v1 = 3;
#  ret.v2 = 3.5;
#  return ret;
#}
#
#int main() {
#  Tuple!(int,float) x = func();
#  writefln("%s %s",x.v1,x.v2);
#
#  int i;
#  float f;
#  func().assignTo(i,f);
#  writefln("%s %s",i,f);
#
#  return 0;
#}

/Oskar

Thanks for both replies.  I would love it if somehow this could be incorporated
into the language or library.  But for the library, I'm guessing that would need
implicit template instantiation?

-Kramer
```
Feb 09 2006
Sean Kelly <sean f4.ca> writes:
```Kramer wrote:

Thanks for both replies.  I would love it if somehow this could be incorporated
into the language or library.  But for the library, I'm guessing that would
need
implicit template instantiation?

Not really.  'auto' is great for this sort of thing:

auto ret = someFunction(x,y,z);
int   a = ret.val!(0);
float b = ret.val!(1);

This is what I'm shooting for anyway.

Sean
```
Feb 09 2006
Sean Kelly <sean f4.ca> writes:
```Sean Kelly wrote:
Kramer wrote:
Is there any way to simulate tuples in D currently?  (hopefully that
doesn't
look too hackish <g>)

Yes.  I just threw this example together so it could do with a bit of
cleaning up, but it works.  My only major complaint is that template
functions can't be overloaded, thus the 'get' and 'set' methods.

It turns out that I was still thinking with a C++ mindset.  No methods
need to be defined at all--this can all be done using consts and
aliases--however, there appears to be a bug preventing this from working
with structs.  I'm going to rewrite the tuple example with classes and
it can be converted to a struct whenever this is fixed.  Stay tuned.

Sean
```
Feb 09 2006
"Walter Bright" <newshound digitalmars.com> writes:
```"Sean Kelly" <sean f4.ca> wrote in message
news:dsgami\$2cvr\$2 digitaldaemon.com...
No methods need to be defined at all--this can all be done using consts
and aliases--however, there appears to be a bug preventing this from
working with structs.

What's the bug?
```
Feb 13 2006
Sean Kelly <sean f4.ca> writes:
```Walter Bright wrote:
"Sean Kelly" <sean f4.ca> wrote in message
news:dsgami\$2cvr\$2 digitaldaemon.com...
No methods need to be defined at all--this can all be done using consts
and aliases--however, there appears to be a bug preventing this from
working with structs.

What's the bug?

It turns out there are two issues.

This is the one regarding different behavior between structs and classes:

digitalmars.D.bugs/6193

And in this one, the compiler doesn't seem to like aliasing scoped
variables:

digitalmars.D.bugs/6195

I narrowed down the above case here:

digitalmars.D.bugs/6197

This last post also included a question--are aliases intended to be used
in this way?  From what was in the spec, I wasn't entirely certain.

Sean
```
Feb 13 2006