Thread overview
tuples and freeze dried function args
Feb 23, 2007
torhu
Feb 23, 2007
Bill Baxter
Feb 28, 2007
torhu
Feb 28, 2007
Bill Baxter
Feb 23, 2007
Kevin Bealer
Feb 23, 2007
Bill Baxter
February 23, 2007
I have a function like this:

void f(int, int, int);


I know that I can do this:

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

alias Tuple!(1, 2, 3) args;


And this now works:

f(args);


But I want to go one step further, and store the args somehow.

alias Tuple!(1, 2, 3) OneSetOfArgs;
alias Tuple!(4, 5, 6) AnotherSetOfArgs;


If I have

struct S { */ ...  */};


can I somehow store OneSetOfArgs in a field, so I can do this?

S s;

s.args = OneSetOfArgs;

f(s.args);  // s.args expands into three ints


I take it the answer is 'no'?

Solutions involving wrapping f, or using assembly is not really what I'm looking for.
February 23, 2007
torhu wrote:
> I have a function like this:
> 
> void f(int, int, int);
> 
> 
> I know that I can do this:
> 
> template Tuple(T...)
> {
>     alias T Tuple;
> }
> 
> alias Tuple!(1, 2, 3) args;
> 
> 
> And this now works:
> 
> f(args);
> 
> 
> But I want to go one step further, and store the args somehow.
> 
> alias Tuple!(1, 2, 3) OneSetOfArgs;
> alias Tuple!(4, 5, 6) AnotherSetOfArgs;
> 
> 
> If I have
> 
> struct S { */ ...  */};
> 
> 
> can I somehow store OneSetOfArgs in a field, so I can do this?
> 
> S s;
> 
> s.args = OneSetOfArgs;
> 
> f(s.args);  // s.args expands into three ints
> 
> 
> I take it the answer is 'no'?
> 
> Solutions involving wrapping f, or using assembly is not really what I'm looking for.

I think you may be able to get something like what you want using type tuples and tupleof.

alias Tuple!(int,int,int) FArgs;
struct S
{
   FArgs OneSetOfArgs;
   FArgs OtherSetOfArgs;
}
S s;
Foo(s.OneSetOfArgs.tupleof);

Or something along those lines maybe?

--bb
February 23, 2007
You can.  I do this in the futurism library, see here:

http://www.dsource.org/projects/futurism/browser/trunk/futurism/future.d

The function make_future and the class template Future do this; the make_future builds a future object which stores a delegate and its arguments.

Later, the program runs the function from these arguments.  There's a lot of other code in that file... I think you can find a simpler example at the bottom of this page:

http://www.digitalmars.com/d/tuple.html

'Functional' programming languages call this 'currying'.

Kevin
February 23, 2007
Kevin Bealer wrote:
> You can.  I do this in the futurism library, see here:
> 
> http://www.dsource.org/projects/futurism/browser/trunk/futurism/future.d
> 
> The function make_future and the class template Future do this; the make_future
> builds a future object which stores a delegate and its arguments.
> 
> Later, the program runs the function from these arguments.  There's a lot of other
> code in that file... I think you can find a simpler example at the bottom of this
> page:
> 
> http://www.digitalmars.com/d/tuple.html

> 'Functional' programming languages call this 'currying'.

Actually they call it "partial function application"

Currying is something else often mistaken for partial evaluation.

Currying is treating a function of N args that returns Ret
    func: (Arg1,Arg2,Arg3) -> Ret
as a function that does partial evaluation "to the max"
    func: Arg1 -> (Arg2 -> (Arg3 -> Ret))
That's a
   function that takes an Arg1 and returns
    (a function that takes an Arg2 and returns
       (a function that takes an Arg3 and returns a Ret))

So the call  func a b c  is treated as (((func a) b ) c) with currying.

In ML for instance, all functions are curried by default (but you can sort of override the behavior by declaring your function to take a tuple as a single argument).

Python has a partial application library that was originally called 'curry' until the functional folks shot it down as a misnomer.  Now it's called 'partial'.
http://www.python.org/dev/peps/pep-0309/

--bb
February 28, 2007
Bill Baxter wrote:
> I think you may be able to get something like what you want using type tuples and tupleof.
> 
> alias Tuple!(int,int,int) FArgs;
> struct S
> {
>     FArgs OneSetOfArgs;
>     FArgs OtherSetOfArgs;
> }
> S s;
> Foo(s.OneSetOfArgs.tupleof);
> 
> Or something along those lines maybe?

That doesn't work.  I tried something like it.

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

struct BlockType {
   Tuple!(int, int, int) color;   // line 34
}

blocktypes.d(34): variable blocktypes.BlockType.color is not a per-instance initializable field

I guess I'll just go with an array for the color.  It was just intended to show off some D features.  But if it's going to get complicated, there's no point to it.  It would just be a silly way of doing something that's really very simple.
February 28, 2007
torhu wrote:
> Bill Baxter wrote:
>> I think you may be able to get something like what you want using type tuples and tupleof.
>>
>> alias Tuple!(int,int,int) FArgs;
>> struct S
>> {
>>     FArgs OneSetOfArgs;
>>     FArgs OtherSetOfArgs;
>> }
>> S s;
>> Foo(s.OneSetOfArgs.tupleof);
>>
>> Or something along those lines maybe?
> 
> That doesn't work.  I tried something like it.
> 
> template Tuple(T...)
> {
>     alias T Tuple;
> }
> 
> struct BlockType {
>    Tuple!(int, int, int) color;   // line 34
> }
> 
> blocktypes.d(34): variable blocktypes.BlockType.color is not a per-instance initializable field
> 
> I guess I'll just go with an array for the color.  It was just intended to show off some D features.  But if it's going to get complicated, there's no point to it.  It would just be a silly way of doing something that's really very simple.

Hmm.  Yeh, if making an anonymous color type is all you want to do with it I'd definitely recommend just using int[3].  No reason to bring in the big guns unless they're really needed.

I like the way Helix does it using anonymous unions:

struct BlockType {
   union {
       int[3] color;
       struct {
          int r;
          int g;
          int b;
       }
   }
}

Then you can use  b.color[2] or b.b whichever suits your needs.

--bb