www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - tuples and freeze dried function args

reply torhu <fake address.dude> writes:
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.
Feb 23 2007
next sibling parent reply Bill Baxter <dnewsgroup billbaxter.com> writes:
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
Feb 23 2007
parent reply torhu <fake address.dude> writes:
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.
Feb 28 2007
parent Bill Baxter <dnewsgroup billbaxter.com> writes:
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
Feb 28 2007
prev sibling parent reply Kevin Bealer <kevinbealer gmail.com> writes:
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
Feb 23 2007
parent Bill Baxter <dnewsgroup billbaxter.com> writes:
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
Feb 23 2007