www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - variadic function: passing args

reply icee <icee_member pathlink.com> writes:
is there a way to pass the ... args from one variadic function to another
variadic function?

consider such case:
void vf1(int a, ...) {

vf2(...);
}
void vf2(...) {
}

can vf2 take _arguments and _argptr from vf1?
Jul 04 2006
next sibling parent reply Walter Bright <newshound digitalmars.com> writes:
icee wrote:
 is there a way to pass the ... args from one variadic function to another
 variadic function?
 
 consider such case:
 void vf1(int a, ...) {
 
 vf2(...);
 }
 void vf2(...) {
 }
 
 can vf2 take _arguments and _argptr from vf1?

No, it works a lot like printf/vprintf. Check out the source to std.format for how to do it.
Jul 04 2006
parent reply icee <icee_member pathlink.com> writes:
In article <e8db27$1hu9$2 digitaldaemon.com>, Walter Bright says...
icee wrote:
 is there a way to pass the ... args from one variadic function to another
 variadic function?
 
 consider such case:
 void vf1(int a, ...) {
 
 vf2(...);
 }
 void vf2(...) {
 }
 
 can vf2 take _arguments and _argptr from vf1?

No, it works a lot like printf/vprintf. Check out the source to std.format for how to do it.

---------------------- Yes, it works if we explicitly pass _arguments and _argptr to a overloaded ones, but it would be sweet if the compiler can do a magic for me, by some special syntax. And even more sometime we have no control on the src which provides the vf2. we can do this for a type safe variadic function in D(or C#?): void vf1(int a, Object[] args...){ vf2(args); } and in Python by pack/unpack: def vf1(a, *args, **kw): vf2(*arg, **kw) return ---------------------- In article <e8dc2l$1jta$1 digitaldaemon.com>, Chris Nicholson-Sauls says...
Maybe if we /did/ have a way it would be better.  Maybe something like:
# vf2(_arguments ... _argptr);

Where the '...' in this case has become an operator meaning to pass these
varargs to the 
callee as such.  Not sure if it'd be the best syntax, but its the simplest
thing that 
comes to mind.

-- Chris Nicholson-Sauls

---------------------------- maybe just vf2(...); is OK??? if this tell the compiler wrap the _arguments _argptr pair of vf1 into the vf2 and call it??? and maybe i'm asking for too much:)
Jul 04 2006
parent reply Chris Nicholson-Sauls <ibisbasenji gmail.com> writes:
icee wrote:
 In article <e8db27$1hu9$2 digitaldaemon.com>, Walter Bright says...
 
icee wrote:

is there a way to pass the ... args from one variadic function to another
variadic function?

consider such case:
void vf1(int a, ...) {

vf2(...);
}
void vf2(...) {
}

can vf2 take _arguments and _argptr from vf1?

No, it works a lot like printf/vprintf. Check out the source to std.format for how to do it.

---------------------- Yes, it works if we explicitly pass _arguments and _argptr to a overloaded ones, but it would be sweet if the compiler can do a magic for me, by some special syntax. And even more sometime we have no control on the src which provides the vf2. we can do this for a type safe variadic function in D(or C#?): void vf1(int a, Object[] args...){ vf2(args); } and in Python by pack/unpack: def vf1(a, *args, **kw): vf2(*arg, **kw) return ---------------------- In article <e8dc2l$1jta$1 digitaldaemon.com>, Chris Nicholson-Sauls says...
Maybe if we /did/ have a way it would be better.  Maybe something like:
# vf2(_arguments ... _argptr);

Where the '...' in this case has become an operator meaning to pass these
varargs to the 
callee as such.  Not sure if it'd be the best syntax, but its the simplest
thing that 
comes to mind.

-- Chris Nicholson-Sauls

---------------------------- maybe just vf2(...); is OK??? if this tell the compiler wrap the _arguments _argptr pair of vf1 into the vf2 and call it??? and maybe i'm asking for too much:)

Well sure, but I thought it might be nice if one could, for example, pop the first couple of values off before passing it. Or maybe be able to build one's varargs from scratch or other such odd thing. No I haven't done anything like that in the past... but it could only be because I wasn't /able/ to do such a thing. :) -- Chris Nicholson-Sauls
Jul 05 2006
parent reply David L. Davis <SpottedTiger yahoo.com> writes:
In article <e8i4kn$133i$1 digitaldaemon.com>, Chris Nicholson-Sauls says...
icee wrote:
 In article <e8db27$1hu9$2 digitaldaemon.com>, Walter Bright says...
 
icee wrote:

is there a way to pass the ... args from one variadic function to another
variadic function?

consider such case:
void vf1(int a, ...) {

vf2(...);
}
void vf2(...) {
}

can vf2 take _arguments and _argptr from vf1?

No, it works a lot like printf/vprintf. Check out the source to std.format for how to do it.

---------------------- Yes, it works if we explicitly pass _arguments and _argptr to a overloaded ones, but it would be sweet if the compiler can do a magic for me, by some special syntax. And even more sometime we have no control on the src which provides the vf2. we can do this for a type safe variadic function in D(or C#?): void vf1(int a, Object[] args...){ vf2(args); } and in Python by pack/unpack: def vf1(a, *args, **kw): vf2(*arg, **kw) return ---------------------- In article <e8dc2l$1jta$1 digitaldaemon.com>, Chris Nicholson-Sauls says...
Maybe if we /did/ have a way it would be better.  Maybe something like:
# vf2(_arguments ... _argptr);

Where the '...' in this case has become an operator meaning to pass these
varargs to the 
callee as such.  Not sure if it'd be the best syntax, but its the simplest
thing that 
comes to mind.

-- Chris Nicholson-Sauls

---------------------------- maybe just vf2(...); is OK??? if this tell the compiler wrap the _arguments _argptr pair of vf1 into the vf2 and call it??? and maybe i'm asking for too much:)

Well sure, but I thought it might be nice if one could, for example, pop the first couple of values off before passing it. Or maybe be able to build one's varargs from scratch or other such odd thing. No I haven't done anything like that in the past... but it could only be because I wasn't /able/ to do such a thing. :) -- Chris Nicholson-Sauls

Chris, You could check out my Diva Class project at: http://spottedtiger.tripod.com/D_Language/D_Diva_Project_XP.html Short description: ----------------- Diva (Dynamically Interconnected Variable Arguments) - Diva.d v0.38 WIP Allows the ability to "get" and "set" data, plus alter D's variadic arguments function parameter layout with methods like "prepend, append, insert, splice, and remove. Class implicitly converts stored values of non-exact types whenever possible, allowing for a polymorphic-like value passing to variables, otherwise it returns a default value, avoiding errors if all possible. The Diva Class is more focused toward flexablity (using automatic value conversion) than on opitmal (speed) peformance (operating on only exact/near-exact types i.e. std.boxer). David L. ------------------------------------------------------------------- "Dare to reach for the Stars...Dare to Dream, Build, and Achieve!" ------------------------------------------------------------------- http://spottedtiger.tripod.com/D_Language/D_Main_XP.html
Jul 06 2006
parent Georg Wrede <georg.wrede nospam.org> writes:
David L. Davis wrote:
 In article <e8i4kn$133i$1 digitaldaemon.com>, Chris Nicholson-Sauls
 says...
 
 icee wrote:
 
 In article <e8db27$1hu9$2 digitaldaemon.com>, Walter Bright
 says...
 
 
 icee wrote:
 
 
 is there a way to pass the ... args from one variadic
 function to another variadic function?
 
 consider such case: void vf1(int a, ...) {
 
 vf2(...); } void vf2(...) { }
 
 can vf2 take _arguments and _argptr from vf1?

No, it works a lot like printf/vprintf. Check out the source to std.format for how to do it.

---------------------- Yes, it works if we explicitly pass _arguments and _argptr to a overloaded ones, but it would be sweet if the compiler can do a magic for me, by some special syntax. And even more sometime we have no control on the src which provides the vf2. we can do this for a type safe variadic function in D(or C#?): void vf1(int a, Object[] args...){ vf2(args); } and in Python by pack/unpack: def vf1(a, *args, **kw): vf2(*arg, **kw) return ---------------------- In article <e8dc2l$1jta$1 digitaldaemon.com>, Chris Nicholson-Sauls says...
 Maybe if we /did/ have a way it would be better.  Maybe
 something like: # vf2(_arguments ... _argptr);
 
 Where the '...' in this case has become an operator meaning to
 pass these varargs to the callee as such.  Not sure if it'd be
 the best syntax, but its the simplest thing that comes to mind.
 
 
 -- Chris Nicholson-Sauls

---------------------------- maybe just vf2(...); is OK??? if this tell the compiler wrap the _arguments _argptr pair of vf1 into the vf2 and call it??? and maybe i'm asking for too much:)

Well sure, but I thought it might be nice if one could, for example, pop the first couple of values off before passing it. Or maybe be able to build one's varargs from scratch or other such odd thing. No I haven't done anything like that in the past... but it could only be because I wasn't /able/ to do such a thing. :) -- Chris Nicholson-Sauls

Chris, You could check out my Diva Class project at: http://spottedtiger.tripod.com/D_Language/D_Diva_Project_XP.html Short description: ----------------- Diva (Dynamically Interconnected Variable Arguments) - Diva.d v0.38 WIP Allows the ability to "get" and "set" data, plus alter D's variadic arguments function parameter layout with methods like "prepend, append, insert, splice, and remove. Class implicitly converts stored values of non-exact types whenever possible, allowing for a polymorphic-like value passing to variables, otherwise it returns a default value, avoiding errors if all possible. The Diva Class is more focused toward flexablity (using automatic value conversion) than on opitmal (speed) peformance (operating on only exact/near-exact types i.e. std.boxer).

Damn, this is yet another thing that should be right in Phobos. (And Ares, etc. of course -- no offense!) Maybe there should be a dsource project simply for gathering loose gems, polishing and uniforming them, and finally pushing them to the "default" libraries?? Such loose gems also exist in Python, CPAN, and actually pretty much everywhere. Some of them are quite easy to port to D.
Jul 07 2006
prev sibling parent reply Chris Nicholson-Sauls <ibisbasenji gmail.com> writes:
icee wrote:
 is there a way to pass the ... args from one variadic function to another
 variadic function?
 
 consider such case:
 void vf1(int a, ...) {
 
 vf2(...);
 }
 void vf2(...) {
 }
 
 can vf2 take _arguments and _argptr from vf1?
 
 

Simply way to do it, is to write vf2 twice, once as a variadic wrapper, and once taking a vararg pair. In other words: # import std .stdarg ; # # void vf2 (...) { vf2(_arguments, _argptr); } # # void vf2 (TypeInfo[] _arguments, va_list _argptr) { # /* real work */ # } Sad to say, this is one time when I do start to miss a preprocessor just a little. It'd be somewhat nice to be able to do: ########## module altvararg ; # import std .stdarg ; # # #define ALT_VARIADIC(FNAME) \ # void FNAME (...) { FNAME(_arguments, _argptr; } \ # void FNAME (TypeInfo[] _arguments, va_list _argptr) # ########## module foo ; # import altvararg ; # # ALT_VARIADIC(vf2) { # /* real work */ # } Maybe if we /did/ have a way it would be better. Maybe something like: # vf2(_arguments ... _argptr); Where the '...' in this case has become an operator meaning to pass these varargs to the callee as such. Not sure if it'd be the best syntax, but its the simplest thing that comes to mind. -- Chris Nicholson-Sauls
Jul 04 2006
parent reply Georg Wrede <georg.wrede nospam.org> writes:
Chris Nicholson-Sauls wrote:
 icee wrote:
 
 is there a way to pass the ... args from one variadic function to another
 variadic function?

 consider such case:
 void vf1(int a, ...) {

 vf2(...);
 }
 void vf2(...) {
 }

 can vf2 take _arguments and _argptr from vf1?

Simply way to do it, is to write vf2 twice, once as a variadic wrapper, and once taking a vararg pair. In other words: # import std .stdarg ; # # void vf2 (...) { vf2(_arguments, _argptr); } # # void vf2 (TypeInfo[] _arguments, va_list _argptr) { # /* real work */ # } Sad to say, this is one time when I do start to miss a preprocessor just a little. It'd be somewhat nice to be able to do: ########## module altvararg ; # import std .stdarg ; # # #define ALT_VARIADIC(FNAME) \ # void FNAME (...) { FNAME(_arguments, _argptr; } \ # void FNAME (TypeInfo[] _arguments, va_list _argptr) # ########## module foo ; # import altvararg ; # # ALT_VARIADIC(vf2) { # /* real work */ # } Maybe if we /did/ have a way it would be better. Maybe something like: # vf2(_arguments ... _argptr); Where the '...' in this case has become an operator meaning to pass these varargs to the callee as such. Not sure if it'd be the best syntax, but its the simplest thing that comes to mind.

Suppose we had a new keyword, variadic. Then the compiler could internally accomplish what you propose, by just rewriting, and no complicated changes are needed! void variadic foo(...) { // real work } Of course, here the "..." is redundant. So maybe the syntax could be even more simple: void foo(...) { // real work } So, in essence, the compiler constructs two functions (instead of one): whateverReturnType foo(...) { // real work } gets rewritten as: whateverReturnType foo(...) { foo(_arguments, _argptr; } whateverReturnType foo(TypeInfo[] _arguments, va_list _argptr) { // real work } Now, another change is of course handy here, and that is, if a function gets invoked like blah = foo(...); then it will be rewritten as: blah = foo(_arguments, _argptr); which should be no big deal to implement, right? Major syntactic sugar, I admit, but then again, the whole ... busines is just that. (Or else we would just pass Object[] type variables, right?) ---- This makes one actually wish for some sugar for manipulation of runtime-generated argument lists! (Lisp, watch out, we're coming!)
Jul 06 2006
parent reply Ivan Senji <ivan.senji_REMOVE_ _THIS__gmail.com> writes:
Georg Wrede wrote:
 Chris Nicholson-Sauls wrote:
 icee wrote:

 is there a way to pass the ... args from one variadic function to
 another
 variadic function?

 consider such case:
 void vf1(int a, ...) {

 vf2(...);
 }
 void vf2(...) {
 }

 can vf2 take _arguments and _argptr from vf1?

Simply way to do it, is to write vf2 twice, once as a variadic wrapper, and once taking a vararg pair. In other words: # import std .stdarg ; # # void vf2 (...) { vf2(_arguments, _argptr); } # # void vf2 (TypeInfo[] _arguments, va_list _argptr) { # /* real work */ # } Sad to say, this is one time when I do start to miss a preprocessor just a little. It'd be somewhat nice to be able to do: ########## module altvararg ; # import std .stdarg ; # # #define ALT_VARIADIC(FNAME) \ # void FNAME (...) { FNAME(_arguments, _argptr; } \ # void FNAME (TypeInfo[] _arguments, va_list _argptr) # ########## module foo ; # import altvararg ; # # ALT_VARIADIC(vf2) { # /* real work */ # } Maybe if we /did/ have a way it would be better. Maybe something like: # vf2(_arguments ... _argptr); Where the '...' in this case has become an operator meaning to pass these varargs to the callee as such. Not sure if it'd be the best syntax, but its the simplest thing that comes to mind.

Suppose we had a new keyword, variadic. Then the compiler could internally accomplish what you propose, by just rewriting, and no complicated changes are needed! void variadic foo(...) { // real work } Of course, here the "..." is redundant. So maybe the syntax could be even more simple: void foo(...) { // real work } So, in essence, the compiler constructs two functions (instead of one): whateverReturnType foo(...) { // real work } gets rewritten as: whateverReturnType foo(...) { foo(_arguments, _argptr; } whateverReturnType foo(TypeInfo[] _arguments, va_list _argptr) { // real work } Now, another change is of course handy here, and that is, if a function gets invoked like blah = foo(...); then it will be rewritten as: blah = foo(_arguments, _argptr);

Nice idea, IMO the compiler should do this for us, but it would be even nicer if we could do something like: blah = foo(...[0..5]); //Pass to foo only the first five arguments
Jul 06 2006
next sibling parent reply pragma <pragma_member pathlink.com> writes:
In article <e8jemv$2pfh$1 digitaldaemon.com>, Ivan Senji says...
Nice idea, IMO the compiler should do this for us, but it would be even
nicer if we could do something like:

blah = foo(...[0..5]); //Pass to foo only the first five arguments

I agree, although I don't like the idea of using "..." explicitly as an identifier. I'd rather see a variation of the "named vararg" syntax like so: void foo(args ...){ writefln("hello world",args); } The only problem with the above case is: what type does 'args' actually have (or in Ivan's example, what type does '...' have)? It could be considered an error to use the "vararg expression" in any context other than as a function argument or parameter, but I can't help but think that it would open up a whole world of expressions if it were a proper type unto itself. - EricAnderton at yahoo
Jul 06 2006
parent reply Kirk McDonald <kirklin.mcdonald gmail.com> writes:
pragma wrote:
 In article <e8jemv$2pfh$1 digitaldaemon.com>, Ivan Senji says...
 
Nice idea, IMO the compiler should do this for us, but it would be even
nicer if we could do something like:

blah = foo(...[0..5]); //Pass to foo only the first five arguments

I agree, although I don't like the idea of using "..." explicitly as an identifier. I'd rather see a variation of the "named vararg" syntax like so: void foo(args ...){ writefln("hello world",args); } The only problem with the above case is: what type does 'args' actually have (or in Ivan's example, what type does '...' have)? It could be considered an error to use the "vararg expression" in any context other than as a function argument or parameter, but I can't help but think that it would open up a whole world of expressions if it were a proper type unto itself. - EricAnderton at yahoo

Well, the answer is obvious: It is a tuple. We are essentially discussing the equivalent of this Python code: def func(*args): # packs function arguments into a tuple print args def main(): a = ("blah", 50, 200.35) # creates a tuple func(1, 2, 3, "apple", 5.0) # call the function with normal args func(*a) # "unpack" the tuple, call the func with it
 main()



("blah", 50, 200.35) Though I'm not sure going quite as far as Python does with tuples is what we'd want for D. However, a proper built-in tuple type would be /damnably/ useful. -- Kirk McDonald Pyd: Wrapping Python with D http://dsource.org/projects/pyd/wiki
Jul 06 2006
parent Chris Nicholson-Sauls <ibisbasenji gmail.com> writes:
Kirk McDonald wrote:
 pragma wrote:
 
 In article <e8jemv$2pfh$1 digitaldaemon.com>, Ivan Senji says...

 Nice idea, IMO the compiler should do this for us, but it would be even
 nicer if we could do something like:

 blah = foo(...[0..5]); //Pass to foo only the first five arguments

I agree, although I don't like the idea of using "..." explicitly as an identifier. I'd rather see a variation of the "named vararg" syntax like so: void foo(args ...){ writefln("hello world",args); } The only problem with the above case is: what type does 'args' actually have (or in Ivan's example, what type does '...' have)? It could be considered an error to use the "vararg expression" in any context other than as a function argument or parameter, but I can't help but think that it would open up a whole world of expressions if it were a proper type unto itself. - EricAnderton at yahoo

Well, the answer is obvious: It is a tuple. We are essentially discussing the equivalent of this Python code: def func(*args): # packs function arguments into a tuple print args def main(): a = ("blah", 50, 200.35) # creates a tuple func(1, 2, 3, "apple", 5.0) # call the function with normal args func(*a) # "unpack" the tuple, call the func with it >>> main() (1, 2, 3, "apple", 5.0) ("blah", 50, 200.35) Though I'm not sure going quite as far as Python does with tuples is what we'd want for D. However, a proper built-in tuple type would be /damnably/ useful.

I've done this same thing before, in ColdC where we have the List Splice Operator ' '. Pointless ColdC example: # public method .pointless(): lock { # var args; # # args = [42, "foo", $root]; # .another( args); # } In this case the method .another() would be called with (42, "foo", $root), as the list variable 'args' has been 'spliced' into its arguments list. I have found it quite useful in that platform at least. Some D analog to this might prove equally useful. The idea of a Tuple datatype also seems potentially promising. In a sense, a Tuple can be directly mapped to a structure, and so can function arguments -- therefore, function arguments can be directly mapped to a Tuple, and vice versa. -- Chris Nicholson-Sauls
Jul 06 2006
prev sibling parent Georg Wrede <georg.wrede nospam.org> writes:
Ivan Senji wrote:
 Georg Wrede wrote:
Chris Nicholson-Sauls wrote:
icee wrote:

is there a way to pass the ... args from one variadic function to
another variadic function?

consider such case:
void vf1(int a, ...) {

vf2(...);
}
void vf2(...) {
}

can vf2 take _arguments and _argptr from vf1?

wrapper, and once taking a vararg pair. In other words: # import std .stdarg ; # # void vf2 (...) { vf2(_arguments, _argptr); } # # void vf2 (TypeInfo[] _arguments, va_list _argptr) { # /* real work */ # } Sad to say, this is one time when I do start to miss a preprocessor just a little. It'd be somewhat nice to be able to do: ########## module altvararg ; # import std .stdarg ; # # #define ALT_VARIADIC(FNAME) \ # void FNAME (...) { FNAME(_arguments, _argptr; } \ # void FNAME (TypeInfo[] _arguments, va_list _argptr) # ########## module foo ; # import altvararg ; # # ALT_VARIADIC(vf2) { # /* real work */ # } Maybe if we /did/ have a way it would be better. Maybe something like: # vf2(_arguments ... _argptr); Where the '...' in this case has become an operator meaning to pass these varargs to the callee as such. Not sure if it'd be the best syntax, but its the simplest thing that comes to mind.

Suppose we had a new keyword, variadic. Then the compiler could internally accomplish what you propose, by just rewriting, and no complicated changes are needed! void variadic foo(...) { // real work } Of course, here the "..." is redundant. So maybe the syntax could be even more simple: void foo(...) { // real work } So, in essence, the compiler constructs two functions (instead of one): whateverReturnType foo(...) { // real work } gets rewritten as: whateverReturnType foo(...) { foo(_arguments, _argptr; } whateverReturnType foo(TypeInfo[] _arguments, va_list _argptr) { // real work }


This would be totally safe, since if some day foo gets explicitly called like foo(TypeInfo[], va_list), then it is obvious that the intent is precisely what we'd expect anyway. In other words: even if it in principle is bad manners to gratuituously create not-asked-for function signatures, in this particular case there is no possibility of any harm.
Now, another change is of course handy here, and that is, if a function
gets invoked like

blah = foo(...);

then it will be rewritten as:

blah = foo(_arguments, _argptr);

Nice idea, IMO the compiler should do this for us, but it would be even nicer if we could do something like: blah = foo(...[0..5]); //Pass to foo only the first five arguments

Yes, that'd be nice. But on deeper thought, in such a case it would be required that the outer function gets its parameters (or at least some of them) in a specific order -- how else would we know to use, say, those [0..5] and not some others? In other words, in that case you'd probably have to define the outer function with at least some of its arguments as non-variadic, from which follows that the whole idea becomes obsolete. ----- Thinking of all this variadic stuff, got me on an unrelated tangent: One could conceptually consider a TypeInfo[] somewhat like a struct definition. Both define a "picture" that contains some "elements" which individually are variables. Along this thought, the va-list is a reference to an instance of such a "struct". This raises the question, would it be useful to have a means (a library function or something directly in the language) of creating a TypeInfo[] from a struct, and vice versa? Would this be useful in this "variadic discussion"? Would this be useful in some totally different area? void myFunc(...) { TypeInfo[] ti = _arguments; createStructType(ti) mystruct; // or some other syntax? mystruct = _argptr; // This actually works already?? // then do something useful with them :-) } Thus, we have created a painting of the variadic arguments. Or, as the reverse, we might create an argument list (later to be sent to a function, for example) at runtime, say from a database or from user interaction, or whatever. --- At this point, I must admit, I just got this idea, and I haven't made any effort at all to figure out whether any of this is of any use. Or if it is totally obsolete? Anyhow, maybe some of the smarter guys around here get some ideas. I just thought I'd blurt this out (even at the risk of making a fool of myself), cause it looked cute. :-)
Jul 07 2006