Thread overview
Returning tuples from functions
May 01, 2007
niovol
May 01, 2007
Daniel Keep
May 01, 2007
Bill Baxter
May 01, 2007
BCS
May 01, 2007
BCS
May 02, 2007
Don Clugston
May 01, 2007
When will it be possible? I have almost no experience in programming on D. But I can't imagine how to solve my problem without using tuples.
May 01, 2007
niovol wrote:
> When will it be possible? I have almost no experience in programming on D. But I can't imagine how to solve my problem without using tuples.

No idea; I'd like to know myself.  That said, you have a few alternatives:

1. Use out parameters.  It's like returning a tuple, except you put them inside the parentheses.

Tuple!(int,int,int) foo()
{
    return Tuple!(1,2,3);
}

Becomes

void foo(out int a, out int b, out int c)
{
    a = 1;
    b = 2;
    c = 3;
}

2. Use Tuple structs.  This is a horrible, nasty trick that is very cool.

struct TupleStruct(T...)
{
    T tuple;

    static TupleStruct!(T) opCall(T args)
    {
        TupleStruct!(T) result;
        foreach( i,a ; args )
            result.tuple[i] = a;
        return result;
    }
}

TupleStruct!(int, int, int) foo()
{
    return TupleStruct!(int, int, int)(1, 2, 3);
}

I believe there is just such a thing in... the standard library somewhere.  Go poking; you'll find it :P

	-- Daniel

-- 
int getRandomNumber()
{
    return 4; // chosen by fair dice roll.
              // guaranteed to be random.
}

http://xkcd.com/

v2sw5+8Yhw5ln4+5pr6OFPma8u6+7Lw4Tm6+7l6+7D i28a2Xs3MSr2e4/6+7t4TNSMb6HTOp5en5g6RAHCP  http://hackerkey.com/
May 01, 2007
niovol wrote:
> When will it be possible? I have almost no experience in programming on D. But I can't imagine how to solve my problem without using tuples.

I don't know either, but if you saw the NWC++ User's Group video of Walter, he said at the end that returning tuples was one of the things he'd like to add.

--bb
May 01, 2007
niovol wrote:
> When will it be possible? I have almost no experience in programming on D. But I can't imagine how to solve my problem without using tuples.

Here's a nasty hack I came up with a while ago

struct SetT(V...)
{
  V args_m;
  void opCall(inout V args)
  {
    foreach (i, arg; args_m) args[i] = arg;
  }
}

SetT!(V) Set(V...)(V args)
{
  SetT!(V) ret;
  foreach (i, arg; args) ret.args_m[i] = arg;
  return ret;
}

//// Usage


SetT!(int,int) bar(int i, int j){ return Set(i,j); }

void main()
{
  int i=1,j=2,k=0,l=0;
  bar(i,j)(k,l);
  writef("[k,l]=[%d,%d]\n", k,l);
}


note: assignment is left-to-right
May 01, 2007
BCS wrote:

> niovol wrote:
>> When will it be possible? I have almost no experience in programming on D. But I can't imagine how to solve my problem without using tuples.
> 
> Here's a nasty hack I came up with a while ago
> 
<snipped the nasty hack>

The only problem is that the struct version is 27 opcodes or 150% longer that the inout/ref version at least on DMD/Linux. These hacks aren't very useful until the optimizer gets better or something else great happens.
May 01, 2007
Reply to Jari-Matti Mäkelä,

> BCS wrote:
> 
>> niovol wrote:
>> 
>>> When will it be possible? I have almost no experience in programming
>>> on D. But I can't imagine how to solve my problem without using
>>> tuples.
>>> 
>> Here's a nasty hack I came up with a while ago
>> 
> <snipped the nasty hack>
> 
> The only problem is that the struct version is 27 opcodes or 150%
> longer that the inout/ref version at least on DMD/Linux. These hacks
> aren't very useful until the optimizer gets better or something else
> great happens.
> 

That's all? I would have expected about a 10x increase in code size.


May 01, 2007
Jari-Matti Mäkelä wrote:

> BCS wrote:
> 
>> niovol wrote:
>>> When will it be possible? I have almost no experience in programming on D. But I can't imagine how to solve my problem without using tuples.
>> 
>> Here's a nasty hack I came up with a while ago
>> 
> <snipped the nasty hack>
> 
> The only problem is that the struct version is 27 opcodes or 150% longer that the inout/ref version at least on DMD/Linux. These hacks aren't very useful until the optimizer gets better or something else great happens.

It would also help the expression template code. I tried to come up with an optimal version of adding matrices with a regular D syntax, but the compiler couldn't remove some of the intermediate structs. I then tried the example code from Don's BLADE, but even it didn't produce optimal code. Has anyone found a solution to this? I don't think an improved optimizer is enough, there should be a way to pass these 'AST references' at compile time.
May 01, 2007
BCS wrote:

> Reply to Jari-Matti Mäkelä,
> 
>> BCS wrote:
>> 
>>> niovol wrote:
>>> 
>>>> When will it be possible? I have almost no experience in programming on D. But I can't imagine how to solve my problem without using tuples.
>>>> 
>>> Here's a nasty hack I came up with a while ago
>>> 
>> <snipped the nasty hack>
>> 
>> The only problem is that the struct version is 27 opcodes or 150% longer that the inout/ref version at least on DMD/Linux. These hacks aren't very useful until the optimizer gets better or something else great happens.
>> 
> 
> That's all? I would have expected about a 10x increase in code size.

Hehe, you're right. Somehow I only calculated the generated code in the main routine. Time to get some sleep :)
May 02, 2007
Jari-Matti Mäkelä wrote:
> Jari-Matti Mäkelä wrote:
> 
>> BCS wrote:
>>
>>> niovol wrote:
>>>> When will it be possible? I have almost no experience in programming on
>>>> D. But I can't imagine how to solve my problem without using tuples.
>>> Here's a nasty hack I came up with a while ago
>>>
>> <snipped the nasty hack>
>>
>> The only problem is that the struct version is 27 opcodes or 150% longer
>> that the inout/ref version at least on DMD/Linux. These hacks aren't very
>> useful until the optimizer gets better or something else great happens.
> 
> It would also help the expression template code. I tried to come up with an
> optimal version of adding matrices with a regular D syntax, but the
> compiler couldn't remove some of the intermediate structs. I then tried the
> example code from Don's BLADE, but even it didn't produce optimal code. Has
> anyone found a solution to this? 
It's a problem; the generated tuple handling code is horrible. I've abandoned the idea of using tuples and expression templates.

I don't think an improved optimizer is
> enough, there should be a way to pass these 'AST references' at compile
> time.

I agree. My latest BLADE experiments use text mixins instead. There are a lot of advantages to doing it this way.
So far, I haven't hooked up the asm code generation, but right now it generates D code in-line. (No function call overhead whatsoever).

Incidentally, I'm also coming to the conclusion that operator overloading is a bit of a flawed concept. For almost every case where you'd want to use them, the code generation is terrible. You really want to see the whole expression before you generate code.

(eg,  a = b + a; can almost always be done more efficiently as a+=b).